Skip to content

Commit

Permalink
修复QQ:284485094提出的bug:C#生成密钥偶尔会有参数位数会少一位,Java生成的就没有这种问题,Java已兼容C# RSAC…
Browse files Browse the repository at this point in the history
…ryptoServiceProvider生成的这种特殊密钥,利于互操作
  • Loading branch information
xiangyuecn committed Sep 30, 2020
1 parent b4d939f commit 2f8b14a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 18 deletions.
49 changes: 31 additions & 18 deletions RSA_PEM.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ public RSA_PEM(RSAPublicKey publicKey, RSAPrivateKey privateKeyOrNull) {
public RSA_PEM(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ) {
Key_Modulus=modulus;
Key_Exponent=exponent;
Key_D=d;
Key_D=BigL(d, modulus.length);

Val_P=p;
Val_Q=q;
Val_DP=dp;
Val_DQ=dq;
Val_InverseQ=inverseQ;
int keyLen = modulus.length / 2;
Val_P=BigL(p, keyLen);
Val_Q=BigL(q, keyLen);
Val_DP=BigL(dp, keyLen);
Val_DQ=BigL(dq, keyLen);
Val_InverseQ=BigL(inverseQ, keyLen);
}
/***
* 通过公钥指数和私钥指数构造一个PEM,会反推计算出P、Q但和原始生成密钥的P、Q极小可能相同
Expand All @@ -79,7 +80,7 @@ public RSA_PEM(byte[] modulus, byte[] exponent, byte[] dOrNull) {
Key_Exponent=exponent;//publicExponent

if(dOrNull!=null) {
Key_D=dOrNull;//privateExponent
Key_D=BigL(dOrNull, modulus.length);//privateExponent

//反推P、Q
BigInteger n = BigX(modulus);
Expand All @@ -96,11 +97,12 @@ public RSA_PEM(byte[] modulus, byte[] exponent, byte[] dOrNull) {
BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
BigInteger coeff = q.modInverse(p);

Val_P=BigB(p);//prime1
Val_Q=BigB(q);//prime2
Val_DP=BigB(exp1);//exponent1
Val_DQ=BigB(exp2);//exponent2
Val_InverseQ=BigB(coeff);//coefficient
int keyLen = modulus.length / 2;
Val_P=BigL(BigB(p), keyLen);//prime1
Val_Q=BigL(BigB(q), keyLen);//prime2
Val_DP=BigL(BigB(exp1), keyLen);//exponent1
Val_DQ=BigL(BigB(exp2), keyLen);//exponent2
Val_InverseQ=BigL(BigB(coeff), keyLen);//coefficient
}
}

Expand Down Expand Up @@ -146,6 +148,15 @@ static public byte[] BigB(BigInteger bigx) {
}
return val;
}
/**某些密钥参数可能会少一位(32个byte只有31个,目测是密钥生成器的问题,只在c#生成的密钥中发现这种参数,java中生成的密钥没有这种现象),直接修正一下就行;这个问题与BigB有本质区别,不能动BigB**/
static public byte[] BigL(byte[] bytes, int keyLen) {
if (keyLen - bytes.length == 1) {
byte[] c = new byte[bytes.length + 1];
System.arraycopy(bytes, 0, c, 1, bytes.length);
bytes = c;
}
return bytes;
}
/**
* 由n e d 反推 P Q
* 资料: https://stackoverflow.com/questions/43136036/how-to-get-a-rsaprivatecrtkey-from-a-rsaprivatekey
Expand Down Expand Up @@ -260,12 +271,14 @@ static public RSA_PEM FromPEM(String pem) throws Exception {
//读取数据
param.Key_Modulus = readBlock(data, idx);
param.Key_Exponent = readBlock(data, idx);
param.Key_D = readBlock(data, idx);
param.Val_P = readBlock(data, idx);
param.Val_Q = readBlock(data, idx);
param.Val_DP = readBlock(data, idx);
param.Val_DQ = readBlock(data, idx);
param.Val_InverseQ = readBlock(data, idx);
int keyLen = param.Key_Modulus.length;
param.Key_D = BigL(readBlock(data, idx), keyLen);
keyLen = keyLen / 2;
param.Val_P = BigL(readBlock(data, idx), keyLen);
param.Val_Q = BigL(readBlock(data, idx), keyLen);
param.Val_DP = BigL(readBlock(data, idx), keyLen);
param.Val_DQ = BigL(readBlock(data, idx), keyLen);
param.Val_InverseQ = BigL(readBlock(data, idx), keyLen);
} else {
throw new Exception("pem需要BEGIN END标头");
}
Expand Down
1 change: 1 addition & 0 deletions Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public static void main(String[] argv) throws Exception{
System.out.println("◆◆◆◆◆◆◆◆◆◆◆◆ RSA测试 ◆◆◆◆◆◆◆◆◆◆◆◆");
System.out.println("---------------------------------------------------------");

//for(int i=0;i<1000;i++){System.out.println("第"+i+"次>>>>>"); RSATest(); }
RSATest();

System.out.println("-------------------------------------------------------------");
Expand Down

0 comments on commit 2f8b14a

Please sign in to comment.