RSA密碼學規范PKCS#1 v2.2
符號說明
- \(n\): RSA模數\(n\);
- \(r_i\): 模數\(n\)的素因子(需是奇素數), \(n=r_1\cdot r_2\cdot \dots\cdot r_u, u \ge 2\);
- \(p,q\): \(n\)的素因子, 滿足\(n=p\cdot q\). 其中\(r_1=p, r_2 = q\);
- \(C\): 密文的八位串字符串表示;
- \(c\): 密文的整數表示, \(0\le c \le (n-1)\);
- \(m\): 消息的整數表示, \(0\le m \le (n-1)\);
- \(M\): 消息的八位串(每8位一組)字符串表示;
- \(s\): 簽名的整數表示, \(0\le s \le (n-1)\);
- \(S\): 簽名的八位串字符串表示;
- \(d\): 私鑰指數, \(e\cdot d \equiv 1\mod \lambda(n)\);
- \(e\): 公鑰指數, \(3 \le e \le (n-1), GCD(e, \lambda(n))=1\);
- \(EM\): 經過一定編碼規則的消息串, 八進制八位串字符串;
- \(d_i\): 素因子\(r_i\)的CRT指數, \(e\cdot d_i\equiv 1 \mod (r_i-1), i=3,\dots, u\);
- \(dP\): \(p\)的CRT指數, \(e\cdot dP \equiv 1\mod (p-1)\);
- \(dQ\): \(q\)的CRT指數, \(e\cdot dQ \equiv 1\mod (q-1)\);
- \(qInv\): CRT系數, \(q\cdot qInv\equiv 1\mod p,\ 0\lt qInv \lt p\);
- \(t_i\): CRT系數, \(R_i\cdot t_i\equiv 1\mod r_i, R_i=r_1\cdot r_2\cdot\dots\cdot r_{i-1}, i = 3,\dots,u\);
- \(\lambda(n)=LCM(r_1-1,r_2-1,\dots,r_u-1)\);
- \(a||b\): 表示將字符串\(b\)拼接在\(a\)后;
- \(len(X)\)表示計算八位串的長度, 即字節長度;
- \(truncate_l(X)\)表示取\(X\)的最左邊(最高有效位)的\(l\)個字節. 如果不足\(l\)個字節則在最高位填充0補齊到\(l\)個字節;
公鑰私鑰的表示
-
公鑰:
- \((n,e)\);
-
私鑰:
- 第一種私鑰表示:
- \((n,d)\);
- 第二種私鑰表示:
- \((p,q,dP,dQ,qInv), (r_i, d_i, t_i)\);
- 第一種私鑰表示:
數據轉換
- I2OSP: 整數轉為八位串字符串;
- OS2IP: 八位串字符串轉為整數;
I2OSP
記有大整數\(x=\sum_{i=0}^{N-1}b_i\cdot 2^{8\cdot i}, N=len(x)\), 則對應的八位串字符串為\(X=b_{N-1}||\dots||b_1||b_0\);
OSP2IP
記有八位串字符串為\(X=b_{N-1}||\dots||b_1||b_0\), 則對應的大整數為\(x=\sum_{i=0}^{N}b_i\cdot 2^{8\cdot i}, N=len(x)\);
密碼學原語
加密RSAEP
\[c = m^e \mod n \]
解密RSADP
- 第一種私鑰表示:
- \(m = c^d \mod n\);
- 第二種私鑰表示:
- \(m_1 = c^{dP}\mod p, m_2 = c^{dQ}\mod q\);
- \(m_i = c^{d_i}\mod r_i, i=3,\dots,u\);
- \(h=(m_1 - m_2)\cdot qInv \mod p\);
- \(m = m_2 + q\cdot h\);
- 初始化\(T=r_1\), \(m = m + (T\cdot r_{i-1})\cdot ((m_i - m)\cdot t_i \mod r_i)\quad for\ i\ from\ 3\ to\ u\)
簽名RSASP1
- 第一種私鑰表示:
- \(s=m^d \mod n\);
- 第二種私鑰表示:
- \(s_1 = m^{dP}\mod p, s_2 = m^{dQ}\mod q\);
- \(s_i = m^{d_i} \mod r_i, i = 3,\dots,u\);
- \(h = (s_1 - s_2)\cdot qInv\mod p\);
- \(s = s_2 + q\cdot h\);
- 初始化\(T=r_1\), \(s = s + (T\cdot r_{i-1})\cdot ((s_i - s)\cdot t_i \mod r_i)\quad for\ i\ from\ 3\ to\ u\)
驗證RSAVP1
\[m = s^e \mod n \]
加密方案
RSAES-OAEP
- 符號說明:
- \(L\): 和消息\(M\)相關聯的標簽, 默認為空字符串;
- \(MGF\): 掩碼生成函數(Mask Generation Function);
RSAES-OAEP-Encrypt
- 檢查長度是否滿足以下要求:
- \(len(L)\)的長度需小於Hash函數對輸入八位串長度的限制;
- \(len(M)\le len(n) - 2\cdot len(HashVal) - 2\);
- EME-OAEP編碼:
- \(lval = Hash(L)\);
- 生成八位串字符串\(PS=0||\dots||0,\ len(PS)=len(n)-len(M)-2\cdot len(HashVal) - 2\);
- 生成八位串字符串\(DB=lval || PS || 0x01 || M\);
- 生成八位串長度為\(len(HashVal)\)的隨機八位串字符串\(seed\);
- \(dbMask = MGF(seed, len(n)-len(HashVal)-1)\);
- \(maskedDB = DB \oplus dbMask\);
- \(seedMask = MGF(maskedDB, len(HashVal))\);
- \(maskSeed = seed \oplus seedMask\);
- \(EM = 0x00 || maskedSeed || maskedDB\);
- RSA加密:
- \(m=OS2IP(EM)\);
- \(c = RSAEP(m)\);
- \(C = truncate_{len(n)}(I2OSP(c))\);
- 輸出\(C\);
RSAES-OAEP-Decrypt
- 檢查長度是否滿足以下要求:
- \(len(L)\)的長度需要小於Hash函數對輸入八位串長度的限制;
- \(len(C) = len(n)\);
- \(len(n) \ge (2*len(HashVal) + 2)\);
- RSA解密:
- \(c=OS2IP(C)\);
- \(m = RSADP(c)\);
- \(EM = truncate_{len(n)}(I2OSP(m))\);
- EME-OAEP解碼:
- \(lval = Hash(L)\);
- \(EM = Y || maskedSeed || maskedDB\);
- \(seedMask = MGF(maskedDB, len(HashVal))\);
- \(seed = maskedSeed \oplus seedMask\);
- \(dbMask = MGF(seed, len(n)-len(HashVal)-1)\);
- \(DB = maskedDB \oplus dbMask\);
- \(DB = lval^{'} || PS || Z || M\);
- 檢查格式是否合法:
- \(Y = 0x00\);
- \(lval = lval^{'}\);
- \(Z = 0x01\);
- 輸出\(M\);
RSAES-PKCS1_v1.5
RSAES-PKCS1_v1.5-Encrypt
- 檢查消息長度是否合規:
- \(len(M) \le (len(n) - 11)\);
- EME-PKCS1-v1.5編碼:
- 隨機生成各字節都非0的八位串: \(PS,\quad len(PS) = len(n)-len(M)-3\);
- \(EM = 0x00||0x02||PS||0x00||M\);
- RSA加密:
- \(m=OS2IP(EM)\);
- \(c = RSAEP(m)\);
- \(C = I2OSP(c)\);
- 輸出\(C\);
RSAES-PKCS_v1.5-Decrypt
- 檢查密文長度是否合規:
- \(len(C) = len(n), len(n) \ge 11\);
- RSA解密:
- \(c = OS2IP(C)\);
- \(m = RSADP(c)\);
- \(EM = I2OSP(m)\);
- EME-PKCS1-v1.5解碼:
- \(EM= X||Y||PS||Z||M\);
- 檢查解碼格式是否合規:
- \(X = 0x00, Y=0x02, Z=0x00\);
- 輸出\(M\);
簽名方案
RSASSA-PSS
RSASSA-PSS-Sign
- EMSA-PSS編碼:
- \(EM = EMSA-PSS-Encode(M, bitslen(n)-1)\);
- RSA簽名:
- \(m = OS2IP(EM)\);
- \(s = RSASP1(m)\);
- \(S = truncate_{len(n)}(I2OSP(s))\);
RSASSA-PSS-Verify
- 檢查簽名長度:
- \(len(S) = len(n)\);
- RSA簽名驗證:
- \(s = OS2IP(S)\);
- \(m = RSAVP1(s)\);
- \(EM = trancate_{emLen}(I2OSP(m)), emLen = \lceil (bitslen(n) - 1) / 8 \rceil\);
- EMSA-PSS驗證:
- \(EMSA-PSS-Verify(M, EM, bitslen(n) - 1)\);
RSASSA-PKCS1-v1.5
RSASSA-PKCS1-v1.5-Sign
- EMSA-PKCS1-v1.5編碼:
- \(EM = EMSA-PKCS1-v1.5-Encode(M)\);
- RSA簽名:
- \(m = OS2IP(EM)\);
- \(s = RSASP1(m)\);
- \(S = I2OSP(s)\);
RSASSA-PKCS1-v1.5-Verify
- 檢查\(len(S) = len(n)\)
- RSA驗證:
- \(s = OS2IP(S)\);
- \(m = RSAVP1(S)\);
- \(EM = I2OSP(m)\);
- EMSA-PKCS1-v1.5編碼:
- \(EM' = EMSA-PKCS1-v1.5-Encode(M)\);
- 檢查\(EM = EM'\);
EMSA-PSS
- \(emBits\): \(OS2IP(EM)\)的最大位長度, \(emLen = \lceil emBits/8 \rceil\);
- \(sLen\): salt的字節長度;
EMSA-PSS-Encode
EMSA-PSS-Encode(M, emBits)
:- 檢查消息的長度是否合規:
- \(len(M)\)小於Hash函數的最大輸入串的長度;
- \(emLen \ge (len(HashVal) + sLen + 2\);
- \(mHash = Hash(M)\);
- 隨機生成長度為\(sLen\)的salt字符串;
- \(M' = 0x00||0x00||0x00||0x00||0x00||0x00||0x00||0x00||mHash||salt\);
- \(H = Hash(M')\);
- \(PS = 0||\dots||0, len(PS)=emLen - sLen - len(H) - 2\);
- \(DB = PS || 0x01 || salt\);
- \(dBMask = MGF(H, emLen - len(H) - 1)\);
- \(maskedDB = DB\oplus dbMask\);
- 將\(maskedDB\)最左邊的\(8*emLen - emBits\)的各位替換為0;
- \(EM = maskedDB || H || 0xbc\);
- 輸出EM;
- 檢查消息的長度是否合規:
EMSA-PSS-Verify
EMSA-PSS-Verify(M, EM, emBits)
:- 檢查消息的長度是否合規:
- \(len(M)\)小於Hash函數的最大輸入串的長度;
- \(emLen \ge (len(HashVal) + sLen + 2\);
- 檢查\(EM\)最右邊的字節是否為\(0xbc\);
- \(EM = maskedDB || H, len(maskedDB) = emLen - len(HashVal) - 1\);
- 檢查\(maskedDB\)最左邊的\(8*emLen - emBits\)的各位是否為0;
- \(dbMask = MGF(H, emLen - len(H) - 1)\);
- \(DB = maskedDB \oplus dbMask\);
- 將\(DB\)的最左邊的\(8*emLen - emBits\)的各位替換為0;
- \(DB = X||Y||salt, len(X) = emLen-len(H)-sLen-2, len(Y)=1\);
- 檢查\(X\)的各位是否為0, 且\(Y=0x01\);
- \(M' = 0x00||0x00||0x00||0x00||0x00||0x00||0x00||0x00||mHash||salt\);
- \(H' = Hash(M')\);
- 檢查是否滿足\(H = H'\);
- 檢查消息的長度是否合規:
EMSA-PKCS1-v1.5
EMSA-PKCS1-v1.5-Encode
- 檢查消息的長度是否合規:
- \(len(M)\)小於Hash函數的最大輸入串的長度;
- \(H = Hash(M)\);
DER(Distinguished Encoding Rules)
:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
- 檢查\(emLen \ge (len(DigestInfo) + 11)\);
- \(PS=0xff||\dots||0xff,\quad len(PS) = emLen - len(DigestInfo) - 3\);
- \(EM = 0x00 || 0x01 || PS || 0x00 || DigestInfo\);
- 輸出\(EM\);
MGF
PKCS#1 v2.2中定義了掩碼生成函數MGF1, 其和標准IEEE 1363-2000, ANSI X9.44-2007中的一致;
- \(MGF1(seed, olen)\):
- \(olen\)表示掩碼函數輸出字串的長度, 需滿足\(olen\lt 2^{32}\cdot len(HashVal)\);
- 初始化\(T\)為空串;
- \(T = T || Hash(seed || truncate_4(I2OSP(i)))\quad for\ i\ from\ 0\ to\ \lceil olen/len(HashVal) \rceil - 1\);
- \(truncate_{olen}(T)\);
參考資料
- PKCS#1 v2.2: RSA Cryptography Standard;