zoukankan      html  css  js  c++  java
  • 数字签名算法rsa

    数字签名算法消息传递模型

    1. 由消息发送方构建密钥对,这里由甲方完成。
    2. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方。

    RSA

    1. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消息发送给乙方,私钥仅用于签名,公钥仅用于验证。

    RSA

    RSA

    RSA数字签名算法源于RSA公钥密码算法的思想,将RSA公钥密码算法按照数字签名的方式运用。RSA数字签名算法是迄今为止应用最为广泛的数字签名算法。 RSA数字签名算法的实现如RSA加密算法一致。RSA数字签名算法主要可分为MD系列和SHA系列。

    1. MD系列主要包括:MD2withRSA和MD5withRSA。
    2. SHA系列主要包括:SHA1withRSA,SHA224withRSA,�SHA256withRSA,SHA384withRSA,SHA512withRSA。

    Java 6提供了MD2withRSA,MD5withRSA,SHA1withRSA支持,其他四中SHA算法第三方加密组建包Bouncy Castle提供支持。

    签名过程:

    过程:

    1)消息发送者产生一个密钥对(私钥+公钥),然后将公钥发送给消息接收者

    2)消息发送者使用消息摘要算法对原文进行加密(加密后的密文称作摘要)

    3)消息发送者将上述的摘要使用私钥加密得到密文--这个过程就被称作签名处理,得到的密文就被称作签名(注意,这个签名是名词)

    4)消息发送者将原文与密文发给消息接收者

    5)消息接收者使用公钥对密文(即签名)进行解密,得到摘要值content1

    6)消息接收者使用与消息发送者相同的消息摘要算法对原文进行加密,得到摘要值content2

    7)比较content1是不是与content2相等,若相等,则说明消息没有被篡改(消息完整性),也说明消息却是来源于上述的消息发送方(因为其他人是无法伪造签名的,这就完成了“抗否认性”和“认证消息来源”)

    RSA: 加密原理

    RSA-Algorithm

    RSA算法演示程序,仅供了解RSA算法实现原理

    RSA算法原理

    • 找出两个"很大"的质数:P & Q
    • N = P * Q
    • M = (P - 1) * (Q - 1)
    • 找出整数E,E与M互质,即除了1之外,没有其他公约数
    • 找出整数D,使得E*D除以M余1,即 (E * D) % M = 1

    经过上述准备工作之后,可以得到:

    • E是公钥,负责加密
    • D是私钥,负责解密
    • N负责公钥和私钥之间的联系
    • 加密算法,假定对X进行加密
      • (X ^ E) % N = Y
    • 根据费尔马小定义,根据以下公式可以完成解密操作
      • (Y ^ D) % N = X

    RSA本身算法的核心思想还是比较简单的,加密、解密算法的区别也只是在乘方取模部分使用的数字有所区别而已

    当然,实际运用要比示例代码复杂得多,由于RSA算法的公钥私钥的长度(模长度)要到1024位甚至2048位才能保证安全, 因此,P、Q、E的选取,公钥、私钥的生成,加密、解密模指数运算都有一定的计算程序,需要依托计算机高速运算来完成。

    公开密钥的好处

    • 简单 就是一些乘除而已
    • 可靠 可以保证产生的密文是统计独立,并且分布均匀的,也就是说:
      • 不论给出多少份明文和对应的密文,也无法根据已知的明文和密文的对应关系,破译出下一份密文
      • N和E可以公开给任何人加密使用,但是只有掌握密钥D的人才可以解密,即使加密者自己也无法解密
    • 灵活 可以产生很多的公钥E和私钥D的组合给不同的加密者

    测试数据说明

    P = 11;
    Q = 13;
    N = 143;
    M = 120;
    
    E = 89;
    D = 209;

    提示:本示例程序仅用于演示,N的数值只有143,能够加密的字符范围有限。

    一个C++实现的算法:

    using namespace std;
    
    
    int Plaintext[100];//明文
    long long Ciphertext[100];//密文
    int n, e = 0, d;
    
    //二进制转换
    int BianaryTransform(int num, int bin_num[])
    {
    
        int i = 0,  mod = 0;
    
        //转换为二进制,逆向暂存temp[]数组中
        while(num != 0)
        {
            mod = num%2;
            bin_num[i] = mod;
            num = num/2;
            i++;
        }
    
        //返回二进制数的位数
        return i;
    }
    
    //反复平方求幂
    long long Modular_Exonentiation(long long a, int b, int n)
    {
        int c = 0, bin_num[1000];
        long long d = 1;
        int k = BianaryTransform(b, bin_num)-1;
    
        for(int i = k; i >= 0; i--)
        {
            c = 2*c;
            d = (d*d)%n;
            if(bin_num[i] == 1)
            {
                c = c + 1;
                d = (d*a)%n;
            }
        }
        return d;
    }
    
    //生成1000以内素数
    int ProducePrimeNumber(int prime[])
    {
        int c = 0, vis[1001];
        memset(vis, 0, sizeof(vis));
        for(int i = 2; i <= 1000; i++)if(!vis[i])
        {
            prime[c++] = i;
            for(int j = i*i; j <= 1000; j+=i)
                vis[j] = 1;
        }
    
        return c;
    }
    
    
    //欧几里得扩展算法
    int Exgcd(int m,int n,int &x)
    {
        int x1,y1,x0,y0, y;
        x0=1; y0=0;
        x1=0; y1=1;
        x=0; y=1;
        int r=m%n;
        int q=(m-r)/n;
        while(r)
        {
            x=x0-q*x1; y=y0-q*y1;
            x0=x1; y0=y1;
            x1=x; y1=y;
            m=n; n=r; r=m%n;
            q=(m-r)/n;
        }
        return n;
    }
    
    //RSA初始化
    void RSA_Initialize()
    {
        //取出1000内素数保存在prime[]数组中
        int prime[5000];
        int count_Prime = ProducePrimeNumber(prime);
    
        //随机取两个素数p,q
        srand((unsigned)time(NULL));
        int ranNum1 = rand()%count_Prime;
        int ranNum2 = rand()%count_Prime;
        int p = prime[ranNum1], q = prime[ranNum2];
    
        n = p*q;
    
        int On = (p-1)*(q-1);
    
    
        //用欧几里德扩展算法求e,d
        for(int j = 3; j < On; j+=1331)
        {
            int gcd = Exgcd(j, On, d);
            if( gcd == 1 && d > 0)
            {
                e = j;
                break;
            }
    
        }
    
    }
    
    //RSA加密
    void RSA_Encrypt()
    {
        cout<<"Public Key (e, n) : e = "<<e<<" n = "<<n<<'
    ';
        cout<<"Private Key (d, n) : d = "<<d<<" n = "<<n<<'
    '<<'
    ';
    
        int i = 0;
        for(i = 0; i < 100; i++)
            Ciphertext[i] = Modular_Exonentiation(Plaintext[i], e, n);
    
        cout<<"Use the public key (e, n) to encrypt:"<<'
    ';
        for(i = 0; i < 100; i++)
            cout<<Ciphertext[i]<<" ";
        cout<<'
    '<<'
    ';
    }
    
    //RSA解密
    void RSA_Decrypt()
    {
        int i = 0;
        for(i = 0; i < 100; i++)
            Ciphertext[i] = Modular_Exonentiation(Ciphertext[i], d, n);
    
        cout<<"Use private key (d, n) to decrypt:"<<'
    ';
        for(i = 0; i < 100; i++)
            cout<<Ciphertext[i]<<" ";
        cout<<'
    '<<'
    ';
    }
    
    
    //算法初始化
    void Initialize()
    {
        int i;
        srand((unsigned)time(NULL));
        for(i = 0; i < 100; i++)
            Plaintext[i] = rand()%1000;
    
        cout<<"Generate 100 random numbers:"<<'
    ';
        for(i = 0; i < 100; i++)
            cout<<Plaintext[i]<<" ";
        cout<<'
    '<<'
    ';
    }
    
    int main()
    {
        Initialize();
    
        while(!e)
            RSA_Initialize();
    
        RSA_Encrypt();
    
        RSA_Decrypt();
    
        return 0;
    }
    

      应该是私钥加密,公钥解密的。

    Ref:

    http://wzhong.logdown.com/posts/234502-rsa-c

    https://github.com/liufan321/RSA-Algorithm

     数字签名算法--RSA

    https://github.com/LexHsu/Summary/blob/master/02-Algorithm/book/5.1-rsa.md#数字签名算法消息传递模型

  • 相关阅读:
    基于webpack的react脚手架
    关于密码的简单加密
    移动端日期控件
    JS中如何巧妙的用事件委托
    JS中关于正则的巧妙操作
    call,apply,bind
    vue常用笔记
    高性能的js第三方库——lodash、 Underscore、async、md5及moment
    Nightwatch——自动化测试(端对端e2e)
    for循环的耗时问题
  • 原文地址:https://www.cnblogs.com/sanghai/p/7525450.html
Copyright © 2011-2022 走看看