RSA數字簽名算法源於RSA公鑰密碼算法的思想,將RSA公鑰密碼算法按照數字簽名的方式運用。RSA數字簽名算法是迄今爲止應用最爲普遍的數字簽名算法。 RSA數字簽名算法的實現如RSA加密算法一致。RSA數字簽名算法主要可分爲MD系列和SHA系列。html
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算法演示程序,僅供瞭解RSA算法實現原理
通過上述準備工做以後,能夠獲得:
(X ^ E) % N = Y
(Y ^ D) % N = X
RSA自己算法的核心思想仍是比較簡單的,加密、解密算法的區別也只是在乘方取模部分使用的數字有所區別而已
固然,實際運用要比示例代碼複雜得多,因爲RSA算法的公鑰私鑰的長度(模長度)要到1024位甚至2048位才能保證安全, 所以,P、Q、E的選取,公鑰、私鑰的生成,加密、解密模指數運算都有必定的計算程序,須要依託計算機高速運算來完成。
簡單
就是一些乘除而已可靠
能夠保證產生的密文是統計獨立,而且分佈均勻的,也就是說:
靈活
能夠產生不少的公鑰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
https://github.com/LexHsu/Summary/blob/master/02-Algorithm/book/5.1-rsa.md#數字簽名算法消息傳遞模型