RSA algorithm and CRT in program
2016-07-05 15:53
651 查看
Explained the way to compute the RSA encryption and decryption in C sharp program, and also the way to calculate of the private key provided you know the public key, P and Q by using the
extended Euclidean algorithm, reference to the Python implementation of RSA.
Testing material with RSA
For understand the using CRT with RSA, refer to this
Link. And I am not going to explain the detail as I am not quite familiar with the math in detail myself.
As long as CRT will speed up the computing of RSA, here suppose we have all the detail as Public modulus, Public Exponent, P, Q, DP1, DQ1 and PQ, we use example as below, as I have tested it, it is valid,
0x80 length of public modulus, below is the value.
83934BA65BFC8C67C9394F1AFA9D3F1025BD8DC13B566B364463A6E2F772391C722D070BA4ED2CDC1A46DD58F1C187BA6153472B63FDF568B32D34F4464528E6711BDE6DC27A8EDCD0631014CC5855DBD6DE73B506044B0B0F2F06082AF68F185F1F88804CF9A71B04864453F029701E2E976340911E97C0B7127DDDD07C4AB7
Public Exponent,below is the value
010001
0x40 – length of P, below is the value,
BBC7927F74C2A55E988059F01FF75011A9ED035C1133D1689079E6AADEDDC641FF7949B15795712A4BDC66FD881D33A1A86FA257291BFF9BB9623410F0D16797
0x40– length of Q, below is the value,
B3607464B59AD805B5E46B47E73C59125140F41DD7384281F11092BF8216D5E3A4F02BA06ECEE0E2A0D9EB511B5AEACA26CF2FFEB46F290B5806556BF39199E1
0x40– length of DP1, below is the value,
B4F74D78E5D69C3680F3D93930255095E55454538B048C40A053CA784BD621360376290DEEE147B14270C3147CF3DF8960E14CEB80E3C9BF92B650852F00303B
0x40– length of DQ1, below is the value,
14DD484C9A8F1B4776C3CDF2BC23D9DC76950E9016039640D5106F71552960D1ACD2BED057733AD7418C7781A4A3EBA17DE8259603D8D6365A93CA05D77BFD21
0x40– length of PQ, below is the value,
998F654098C0B83C27D4E55C562FEB9F3774D1B5F850422BDA573973CEBA520614E74527B9CF6D874181741DD3C01E4A488782BC3194EACCA8F6F78661D76C75
Private exponent(d) as below,
4EDD50F0CC1E1A4273386893F137A37F183FFFE19CA175EDB71C4C01AAF3CA0BA4DC1C66FC5A351350A4BD33FCE455687FC19CDD03384B8A902B3E9C542A4C12C812D25464DAB78815D2C8287FFA35949697B83EEEC437F6C92FA22149DDD5336C7A8A10CF165F3EED42F4FBFC362493D7D68C3641A0D36CFA015EBB6188DE81
We use below value as the plain text to encrypt:
004AA63B4EB37767D863C8EF8139E1DE8A04DDD7FC96C8C0897B0094F95736DA28C79B8862F636327CABD310251BB2169F2A9692D5C434B9CE627E88FD3591AED6B693557D60A44F1CA53321B83F9C4EC11CF8F75F46AD39ECD318542299587E1A4638AF03F98C338F0043E2DD917F4C2CC67B490FE7323A25BE480B7BED469E
Encrypted text as below,
6ED55DE6502C37EC2D4AA5B88752EEE88F89F246AE49432B4C02058CFADAB08A716049EDC04BE4CC1B40C889C3F726671A5E5CFD5CAEECAE01DB5FA06B7745DC7DE56818D2D0179F50EAF9C328CAB16303D5D47E30A98F477B9A9C76AE4017568F341944A832A0CF747A8FB93322D884D7F9D0DBE3737C39E44BF0954090ACD2
Can use this
link to verify the RSA encryption and decryption result.
Make sure you have the correct version Visual studio to import "System.Numerics" support. as below screenshot,
To convert from hex string on the GUI to the byte array, can refer to this
Link, by using below methods,
Convert all the RSA parameters to the BigIntegers,
Verify M = P*Q
Calculate the private key D,
link. The source code is as below,
After calculate the private key D, display on the GUI.
Verify the DQ,
Verify DP,
Verify PQ,
link (Modulus size - 11. (11 bytes is the minimum padding possible.)). ,
instead I am using the BigInteger calculation, but not sure it will work in all the case, but at least it works at my example material above,
Link, by using below methods,
is LittleEndian,
It is much easier to convert from BigInteger to the hex string and display on the GUI,
Link, and source code download from
Here. The software screenshot is as below,
Reference:
1,
RSA Algorithm in Wiki
2,
Extended Euclidean algorithm in Wiki
3,
Using the CRT with RSA
4,
Finding the modular inverse
5, RSACryptoServiceProvider.Encrypt Method (Byte[], Boolean)
6, Big number equation calculation
7,
how-to-calculate-d-for-rsa-encryption-from-p-q-and-e
8, http://www.di-mgt.com.au/euclidean.html#extendedeuclidean href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
9, http://www.di-mgt.com.au/crt_rsa.html
10, Why is RSAParameters Modulus not equal product of P and Q?
11,
Mapping RSA Encryption Parameters from CRT (Chinese remainder theorem) to .NET format
12,
RSA: Private key calculation with Extended Euclidean Algorithm
13,
RSA Encryption Problem [Size of payload data]
14,
Signing a byte array of 128 bytes with RSA in C sharp
15,
Bad length in RSACryptoserviceProvider
16,
Converting Hex String To Corresponding Byte Array Using C#
Below references are for the Python implement RSA computing,
17, http://nmichaels.org/rsa.py
18, https://pypi.python.org/pypi/rsa#downloads href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
19, https://stuvel.eu/python-rsa-doc/usage.html#key-size-requirements href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
20, https://bitbucket.org/nmichaels/rsatool/src href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
21, https://pypi.python.org/pypi/pycrypto href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
extended Euclidean algorithm, reference to the Python implementation of RSA.
Testing material with RSA
For understand the using CRT with RSA, refer to thisLink. And I am not going to explain the detail as I am not quite familiar with the math in detail myself.
As long as CRT will speed up the computing of RSA, here suppose we have all the detail as Public modulus, Public Exponent, P, Q, DP1, DQ1 and PQ, we use example as below, as I have tested it, it is valid,
0x80 length of public modulus, below is the value.
83934BA65BFC8C67C9394F1AFA9D3F1025BD8DC13B566B364463A6E2F772391C722D070BA4ED2CDC1A46DD58F1C187BA6153472B63FDF568B32D34F4464528E6711BDE6DC27A8EDCD0631014CC5855DBD6DE73B506044B0B0F2F06082AF68F185F1F88804CF9A71B04864453F029701E2E976340911E97C0B7127DDDD07C4AB7
Public Exponent,below is the value
010001
0x40 – length of P, below is the value,
BBC7927F74C2A55E988059F01FF75011A9ED035C1133D1689079E6AADEDDC641FF7949B15795712A4BDC66FD881D33A1A86FA257291BFF9BB9623410F0D16797
0x40– length of Q, below is the value,
B3607464B59AD805B5E46B47E73C59125140F41DD7384281F11092BF8216D5E3A4F02BA06ECEE0E2A0D9EB511B5AEACA26CF2FFEB46F290B5806556BF39199E1
0x40– length of DP1, below is the value,
B4F74D78E5D69C3680F3D93930255095E55454538B048C40A053CA784BD621360376290DEEE147B14270C3147CF3DF8960E14CEB80E3C9BF92B650852F00303B
0x40– length of DQ1, below is the value,
14DD484C9A8F1B4776C3CDF2BC23D9DC76950E9016039640D5106F71552960D1ACD2BED057733AD7418C7781A4A3EBA17DE8259603D8D6365A93CA05D77BFD21
0x40– length of PQ, below is the value,
998F654098C0B83C27D4E55C562FEB9F3774D1B5F850422BDA573973CEBA520614E74527B9CF6D874181741DD3C01E4A488782BC3194EACCA8F6F78661D76C75
Private exponent(d) as below,
4EDD50F0CC1E1A4273386893F137A37F183FFFE19CA175EDB71C4C01AAF3CA0BA4DC1C66FC5A351350A4BD33FCE455687FC19CDD03384B8A902B3E9C542A4C12C812D25464DAB78815D2C8287FFA35949697B83EEEC437F6C92FA22149DDD5336C7A8A10CF165F3EED42F4FBFC362493D7D68C3641A0D36CFA015EBB6188DE81
We use below value as the plain text to encrypt:
004AA63B4EB37767D863C8EF8139E1DE8A04DDD7FC96C8C0897B0094F95736DA28C79B8862F636327CABD310251BB2169F2A9692D5C434B9CE627E88FD3591AED6B693557D60A44F1CA53321B83F9C4EC11CF8F75F46AD39ECD318542299587E1A4638AF03F98C338F0043E2DD917F4C2CC67B490FE7323A25BE480B7BED469E
Encrypted text as below,
6ED55DE6502C37EC2D4AA5B88752EEE88F89F246AE49432B4C02058CFADAB08A716049EDC04BE4CC1B40C889C3F726671A5E5CFD5CAEECAE01DB5FA06B7745DC7DE56818D2D0179F50EAF9C328CAB16303D5D47E30A98F477B9A9C76AE4017568F341944A832A0CF747A8FB93322D884D7F9D0DBE3737C39E44BF0954090ACD2
Can use this
link to verify the RSA encryption and decryption result.
Verify the CRT parameters are valid
The interface of the RSA computing GUI is as below screenshot shows,Make sure you have the correct version Visual studio to import "System.Numerics" support. as below screenshot,
To convert from hex string on the GUI to the byte array, can refer to this
Link, by using below methods,
public static byte[] ConvertToByteArray(string value)
Convert all the RSA parameters to the BigIntegers,
BigInteger P = Program.FromBigEndian(P2); BigInteger Q = Program.FromBigEndian(Q2); BigInteger DP = Program.FromBigEndian(DP2); BigInteger DQ = Program.FromBigEndian(DQ2); BigInteger InverseQ = Program.FromBigEndian(InverseQ2); BigInteger E = Program.FromBigEndian(Exponent2); BigInteger M = Program.FromBigEndian(Modulus2); BigInteger M1 = BigInteger.Multiply(P, Q); // M = P*Q
Verify M = P*Q
if (M1.CompareTo(M) == 0) { //MessageBox.Show("Modulus is correct!"); } else { MessageBox.Show("Modulus is not correct as M!=P*Q"); return; }
Calculate the private key D,
BigInteger PMinus1 = BigInteger.Subtract(P, BigInteger.One); // P-1 BigInteger QMinus1 = BigInteger.Subtract(Q, BigInteger.One); // Q-1 BigInteger Phi = BigInteger.Multiply(PMinus1, QMinus1); BigInteger D1 = Program.modinv(E, Phi);Here the Program.modinv(E, Phi) is to use the Extended Euclidean algorithm to calculate the modular inverse, the result is the private key D, E is the public key, refer to this
link. The source code is as below,
public static BigInteger modinv(BigInteger u, BigInteger v) { BigInteger inv, u1, u3, v1, v3, t1, t3, q; BigInteger iter; /* Step X1. Initialise */ u1 = 1; u3 = u; v1 = 0; v3 = v; /* Remember odd/even iterations */ iter = 1; /* Step X2. Loop while v3 != 0 */ while (v3 != 0) { /* Step X3. Divide and "Subtract" */ q = u3 / v3; t3 = u3 % v3; t1 = u1 + q * v1; /* Swap */ u1 = v1; v1 = t1; u3 = v3; v3 = t3; iter = -iter; } /* Make sure u3 = gcd(u,v) == 1 */ if (u3 != 1) return 0; /* Error: No inverse exists */ /* Ensure a positive result */ if (iter < 0) inv = v - u1; else inv = u1; return inv; }
After calculate the private key D, display on the GUI.
Verify the DQ,
BigInteger DQ1 = BigInteger.Remainder(D, QMinus1); // dQ = (1/e) mod (q-1) if (DQ1.CompareTo(DQ) == 0) { //Console.WriteLine(" DQ Ok :)"); } else { MessageBox.Show("DQ1 is not correct as dQ = (1/e) mod (q-1)"); return; }
Verify DP,
BigInteger DP1 = BigInteger.Remainder(D, PMinus1); // dP = (1/e) mod (p-1) if (DP1.CompareTo(DP) == 0) { //Console.WriteLine(" DP Ok :)"); } else { MessageBox.Show("DP1 is not correct as dP != (1/e) mod (p-1)"); return; }
Verify PQ,
//qInv = (1/q) mod p BigInteger InverseQ1 = Program.modinv(Q, P); if (InverseQ1.CompareTo(InverseQ) == 0) { //Console.WriteLine(" qInv = (1/q) mod p Ok :)"); } else { MessageBox.Show("InverseQ1 is not correct as qInv = (1/q) mod p"); return; }
RSA encryption and decryption
By using the C# function to encrypt and decrypt, there will be length restriction, 1024 bit length key may only encrypt 117 bytes material, refer to thislink (Modulus size - 11. (11 bytes is the minimum padding possible.)). ,
rsa.ImportParameters(Program.key); byte[] encoded = rsa.Encrypt(input, false); // byte[] encoded = rsa.Decrypt(input, false);
instead I am using the BigInteger calculation, but not sure it will work in all the case, but at least it works at my example material above,
BigInteger c = Program.FromBigEndian(input); BigInteger m = BigInteger.ModPow(c, D, M); //decrypt //BigInteger c = BigInteger.ModPow(m, E, M); //encrypt if it is encryption, it will like this line.. byte[] Plaintext = ConvertToByteArray(m.ToString("X")); if (Plaintext[0] == 0x0) { byte[] newPlaintext = new byte[Plaintext.Length - 1]; //remove the first 0x00 Array.Copy(Plaintext, 1, newPlaintext, 0, Plaintext.Length - 1); result_txt.Text = ByteArrayToHex(newPlaintext); //remove first 0 } else { result_txt.Text = ByteArrayToHex(Plaintext); }
String, Array, BigInteger convert in process
As above mentioned, to convert from hex string on the GUI to the byte array, can refer to thisLink, by using below methods,
public static byte[] ConvertToByteArray(string value)After converted to byte array, then converted to BigInteger, here if the highest bit is 1, needs to add 0x00 at the beginning to prevent the negative value, and we can see there is Array.Reverse() function call, it seems Microsoft BigInteger
is LittleEndian,
public static BigInteger FromBigEndian(byte[] p) { Array.Reverse(p); if (p[p.Length - 1] > 127) { Array.Resize(ref p, p.Length + 1); //this is to prevent the negative value. p[p.Length - 1] = 0; } return new BigInteger(p); }
It is much easier to convert from BigInteger to the hex string and display on the GUI,
byte[] C = ConvertToByteArray(c.ToString("X")); result_txt.Text = ByteArrayToHex(C);
RSA compute in Python
There is Python program available online to calculate RSA, refer to thisLink, and source code download from
Here. The software screenshot is as below,
Reference:
1,
RSA Algorithm in Wiki
2,
Extended Euclidean algorithm in Wiki
3,
Using the CRT with RSA
4,
Finding the modular inverse
5, RSACryptoServiceProvider.Encrypt Method (Byte[], Boolean)
6, Big number equation calculation
7,
how-to-calculate-d-for-rsa-encryption-from-p-q-and-e
8, http://www.di-mgt.com.au/euclidean.html#extendedeuclidean href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
9, http://www.di-mgt.com.au/crt_rsa.html
10, Why is RSAParameters Modulus not equal product of P and Q?
11,
Mapping RSA Encryption Parameters from CRT (Chinese remainder theorem) to .NET format
12,
RSA: Private key calculation with Extended Euclidean Algorithm
13,
RSA Encryption Problem [Size of payload data]
14,
Signing a byte array of 128 bytes with RSA in C sharp
15,
Bad length in RSACryptoserviceProvider
16,
Converting Hex String To Corresponding Byte Array Using C#
Below references are for the Python implement RSA computing,
17, http://nmichaels.org/rsa.py
18, https://pypi.python.org/pypi/rsa#downloads href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
19, https://stuvel.eu/python-rsa-doc/usage.html#key-size-requirements href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
20, https://bitbucket.org/nmichaels/rsatool/src href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
21, https://pypi.python.org/pypi/pycrypto href="https://simple.wikipedia.org/wiki/RSA_(algorithm)" target=_blank>
相关文章推荐
- OpenSSL编程之RSA
- 每 172 个活动 RSA 证书中就有一个容易受到攻击
- C#自定义RSA加密解密及RSA签名和验证类实例
- 使用openssl实现rsa非对称加密算法示例
- php rsa加密解密使用详解
- php实现RSA加密类实例
- PHP rsa加密解密使用方法
- python实现RSA加密(解密)算法
- python使用rsa加密算法模块模拟新浪微博登录
- RDP 协议组件 X.224 在协议流中发现一个错误并且中断了客户端连接的解决方法
- 使用python实现rsa算法代码
- Python使用Pycrypto库进行RSA加密的方法详解
- RSA,AES,MD5算法在实际项目中的综合应用!!!
- 非对称加密RSA算法实现
- Secure CRT 乱码问题解决
- RSA原理与实例
- php rsa加密解密使用详解
- java RSA加密解密
- secure crt常用快捷键
- openssl0.9.8编程生成RSA密钥对(探讨篇)(windows XP SP2+VC6.0)【转】