數字簽名算法rsa

數字簽名算法消息傳遞模型

  1. 由消息發送方構建密鑰對,這裏由甲方完成。
  2. 由消息發送方公佈公鑰至消息接收方,這裏由甲方將公鑰公佈給乙方。

RSA

  1. 注意如加密算法區別,這裏甲方使用私鑰對數據簽名,數據與簽名造成一則消息發送給乙方,私鑰僅用於簽名,公鑰僅用於驗證。

RSA

RSA

RSA數字簽名算法源於RSA公鑰密碼算法的思想,將RSA公鑰密碼算法按照數字簽名的方式運用。RSA數字簽名算法是迄今爲止應用最爲普遍的數字簽名算法。 RSA數字簽名算法的實現如RSA加密算法一致。RSA數字簽名算法主要可分爲MD系列和SHA系列。html

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

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

 

簽名過程:c++

過程:git

1)消息發送者產生一個密鑰對(私鑰+公鑰),而後將公鑰發送給消息接收者github

2)消息發送者使用消息摘要算法對原文進行加密(加密後的密文稱做摘要)算法

3)消息發送者將上述的摘要使用私鑰加密獲得密文--這個過程就被稱做簽名處理,獲得的密文就被稱做簽名(注意,這個簽名是名詞)數組

4)消息發送者將原文與密文發給消息接收者安全

5)消息接收者使用公鑰對密文(即簽名)進行解密,獲得摘要值content1ruby

6)消息接收者使用與消息發送者相同的消息摘要算法對原文進行加密,獲得摘要值content2dom

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<<'\n';
    cout<<"Private Key (d, n) : d = "<<d<<" n = "<<n<<'\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:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Ciphertext[i]<<" ";
    cout<<'\n'<<'\n';
}

//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:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Ciphertext[i]<<" ";
    cout<<'\n'<<'\n';
}


//算法初始化
void Initialize()
{
    int i;
    srand((unsigned)time(NULL));
    for(i = 0; i < 100; i++)
        Plaintext[i] = rand()%1000;

    cout<<"Generate 100 random numbers:"<<'\n';
    for(i = 0; i < 100; i++)
        cout<<Plaintext[i]<<" ";
    cout<<'\n'<<'\n';
}

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#數字簽名算法消息傳遞模型

相關文章
相關標籤/搜索