RSA加解密算法以及密鑰格式


RSA算法:

有個文章關於RSA原理講的不錯:

https://blog.csdn.net/dbs1215/article/details/48953589

http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html

RSA 相關名詞

RSA代表的是一種算法

PKCS 代表的這種算法的一系列標准

 

原始算法定義:

RSA的算法涉及三個參數,n、e1、e2。其中,n是兩個大質數p、q的積,n的二進制表示時所占用的位數,就是所謂的密鑰長度。e1和e2是一對相關的值,e1可以任意取,

要求e1與(p-1)*(q-1)互質

再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。

    (n,e1),(n,e2)就是密鑰對。其中(n,e1)為公鑰,(n,e2)為私鑰。

    RSA加解密的算法完全相同,設A為明文,B為密文,則:

    A=B^e2 mod n;

    B=A^e1 mod n;

公鑰加密體制中,一般用公鑰加密,私鑰解密

e1和e2可以互換使用,即:

    A=B^e1 mod n;

    B=A^e2 mod n;

具體實用產生密文過程:

對於非數學,或者不需要做加密解密等工作的人,我覺得了解下面這些就夠了:

公鑰     (E,N)
私鑰     (D,N)
密鑰對     (E,D,N)
加密     密文=明文EmodN
解密     明文=密文DmodN

 

計算過程:

求N     N= p * q ;p,q為質數
求L     L=lcm(p-1,q-1) ;L為p-1、q-1的最小公倍數
求E     1 < E < L,gcd(E,L)=1;E,L最大公約數為1(E和L互質)
求D     1 < D < L,E*D mod L = 1

 

具體名詞:

1. 密鑰長度:

n的二進制表示時所占用的位數,就是所謂的密鑰長度。

RSA 算法中的密鑰長度是非常長的,介於 512 - 65536 之間(JDK 中默認長度是1024),但是必須是64 的倍數。

 

密鑰:

密鑰的存儲結構:

密鑰的存儲結構有很多,現在先用pem的PKCS#1為例說明:

在PKCS#1 RSA算法標准中定義RSA私鑰語法為:

 RSAPrivateKey ::= SEQUENCE {

version Version,

modulus INTEGER, -- n

publicExponent INTEGER, -- e

privateExponent INTEGER, -- d

prime1 INTEGER, -- p

prime2 INTEGER, -- q

exponent1 INTEGER, -- d mod (p-1)

exponent2 INTEGER, -- d mod (q-1)

coefficient INTEGER, -- (inverse of q) mod p

otherPrimeInfos OtherPrimeInfos OPTIONAL

}

類型RSAPrivateKey 的各域具有以下意義:

• version 是版本號,為了與本文檔的今后版本兼容。本篇文檔的這個版本號應該是0,如果使用了多素數,則版本號應該是1。

Version ::= INTEGER { two-prime(0), multi(1) }

(CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})

• modulus 是RSA合數模n。

• publicExponent 是RSA的公開冪e。

• privateExponent 是RSA的私有冪d。

• prime1 是n的素數因子p。

• prime2 i是n的素數因子q。

• exponent1 等於d mod (p − 1)。

• exponent2 等於d mod (q − 1)。

• coefficient 是CRT系數 q–1 mod p。

• otherPrimeInfos 按順序包含了其它素數r3, …, ru的信息。如果version是0 ,它應該被忽略;而如果version是1,它應該至少包含OtherPrimeInfo的一個實例。

OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo

OtherPrimeInfo ::= SEQUENCE {

prime INTEGER, -- ri

exponent INTEGER, -- di

coefficient INTEGER -- ti

}

OtherPrimeInfo的各域具有以下意義:

• prime 是n的一個素數因子ri ,其中i ≥ 3。

• exponent 是di = d mod (ri − 1)。

• coefficient 是CRT系數 ti = (r1 · r2 · … · ri–1)–1 mod ri。

 

公鑰語法為:

RSAPublicKey ::= SEQUENCE {

modulus INTEGER, -- n

publicExponent INTEGER -- e

}

類型RSAPublicKey的域具有以下意義:

• modulus 是RSA的合數模n。

• publicExponent 是RSA公開冪e。

 

pem 就是將以上數據結構用TLV格式組裝成文件,存儲起來。

公用文件實例:

1. 假設文件內容如下:

1.modulus:
AB602562101207D05A6C413E24CE42699210388F5D31D28151E0FA9141D9C8F8
AC716C0C4F449616AA2270F1007CF3BA46F05131E402266B2A628F4B70142429
93F5BC06E3C0609F9E52BE8D5D0CFACF53C2EE98533A9818828EC5CB8120A688
ADC603DBE65DF9059AD8039644897896943912D81C76856AB7E380C1530C6DE0
E155D4C9FB943967C52EB147CDBF2464AC2B631055DBE3109491A067567AE515
FD36428930FABCAC7C0FEB906C11815B6F00462E588DEB81C4364E2B62540E92
69F49487CC4F8724DDC481C5134B86108C9FACD5D7187706ACA2D3425BFE4F11
9C254273FA5C91EEA5EB06154936D27EE62266CDCAE9E34D20229360559325C7

2.publicExponent:
00000003

2。

組裝PEM文件

1.按照以上數據域順序依次組裝成TLV。
①modulus組裝
0282010100
AB602562101207D05A6C413E24CE42699210388F5D31D28151E0FA9141D9C8F8
AC716C0C4F449616AA2270F1007CF3BA46F05131E402266B2A628F4B70142429
93F5BC06E3C0609F9E52BE8D5D0CFACF53C2EE98533A9818828EC5CB8120A688
ADC603DBE65DF9059AD8039644897896943912D81C76856AB7E380C1530C6DE0
E155D4C9FB943967C52EB147CDBF2464AC2B631055DBE3109491A067567AE515
FD36428930FABCAC7C0FEB906C11815B6F00462E588DEB81C4364E2B62540E92
69F49487CC4F8724DDC481C5134B86108C9FACD5D7187706ACA2D3425BFE4F11
9C254273FA5C91EEA5EB06154936D27EE62266CDCAE9E34D20229360559325C7

說明:
02 - tag  1byte 固定長度 T
82 - 81代表長度用1byte表示,82代表長度用2byte表示 L
0101 - length 2bytes表示 L 跟上面部分共同組成L 長度不固定 見注釋
00 - 在modulus數據前添加00。 見注釋

modules 正常應該是base64存儲

②publicExponent組裝:
020103

說明:
02 - tag T
01 - length L
03 - 00000003 在公鑰組裝中,舍棄0x00;私鑰組裝中,保留0x00 V

2.輸出PEM文件
①公鑰PEM文件頭,嵌套多層TLV,本實例文件頭為:
30820120 300d06092a864886f70d0101010500 0382010d 0030820108

說明:
30820120 文件總的說明 標簽頭
30 - tag
82 - 代表length由2bytes表示
0120 - length (2bytes) 代表本文件有288個byte

30 0d 06092a864886f70d0101010500 這13個字節代表的含義,后續再研究
30 - tag
0d - length
06092a864886f70d0101010500 - value

03 82 010d 00。269個字節,組裝的整體的實際內容:module和publicExponent
03 - tag
82 - 代表length由2bytes表示
010d - value (2bytes),代表長度

00 - 補0x00,

 

3082 0108  組裝的整體的實際內容:module和publicExponent
30 - tag
82 - 代表length由2bytes表示
0108 - value(2bytes),代表長度。

②依次輸出以上組裝后的數據到PEM文件。

至此,PEM文件已生成。

 

注:

長度確定方式 ,也就是L的編碼:

編碼長度,一種是只用一個字節表示長度,其最高位為0,后7位表示長度值,顯然這樣只能表示0-127。另一種是第一個字節的最高位為1,其他位表示后面還有多少個字節屬於Length octets(>=0x80)。后面的那些字節組成的就是長度值。長度值表示的是Contents octets所占的字節數。DER要求如果長度為0-127則要使用第一種方式,如果大於127則使用后一種方式。

1)上述TLV結構中:

V值長度<0x80,L表示數據的長度;

V值長度>=0x80的時候,L為0x8X,X表示的L長度要占用的字節數,X個字節用來表示V的長度。

2)RSA公鑰N的第一個字節如果大於0x80,則需要在公鑰值前面補00,這是因為modulus 為一個大整數,最高位為符號位,其為1時,就是負數,所以要在最高位填充0x00以保證不為負。所以公鑰TLV應該是:02 81 81 00 [128字節個公鑰值]。

3)RSA私鑰的N,d,p,q,Dp,Dq,Mp也需要考慮(2)中的第一個字節如果大於0x80的情況。

4)

TLV一種可變格式,TLV的意思就是:Type類型, Lenght長度,Value值;

 

Type和Length的長度固定,一般那是2、4個字節;

 

Value的長度有Length指定;

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com