代码已经好了,综合的#5 和 #7 链接中的算法,经过简单测试没有问题。还需要更多的测试,有时间这个java版的也会开源
/***
* 通过公钥指数和私钥指数构造一个PEM
**/
public RSA_PEM(byte[] modulus, byte[] exponent, byte[] dOrNull) {
Key_Modulus=modulus;//modulus
Key_Exponent=exponent;//publicExponent
if(dOrNull!=null) {
Key_D=dOrNull;//privateExponent
//反推P、Q
BigInteger n = BigX(modulus);
BigInteger e = BigX(exponent);
BigInteger d = BigX(dOrNull);
BigInteger p = findFactor(e, d, n);
BigInteger q = n.divide(p);
if (p.compareTo(q) > 0) {
BigInteger t = p;
p = q;
q = t;
}
BigInteger exp1 = d.mod(p.subtract(BigInteger.ONE));
BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
BigInteger coeff = q.modInverse(p);
Val_P=p.toByteArray();//prime1
Val_Q=q.toByteArray();//prime2
Val_DP=exp1.toByteArray();//exponent1
Val_DQ=exp2.toByteArray();//exponent2
Val_InverseQ=coeff.toByteArray();//coefficient
}
}
/**java byte是负数,需要加前导0转成正整数**/
static public BigInteger BigX(byte[] data) {
if(data[0]<0) {
byte[] c=new byte[data.length+1];
System.arraycopy(data,0,c,1,data.length);
data=c;
}
return new BigInteger(data);
}
private static BigInteger findFactor(BigInteger e, BigInteger d, BigInteger n) {
BigInteger edMinus1 = e.multiply(d).subtract(BigInteger.ONE);
int s = edMinus1.getLowestSetBit();
BigInteger t = edMinus1.shiftRight(s);
long now=System.currentTimeMillis();
for (int aInt = 2; true; aInt++) {
if(aInt%1000==0 && System.currentTimeMillis()-now>3000) {
throw new RuntimeException("推算RSA.P超时");
}
BigInteger aPow = BigInteger.valueOf(aInt).modPow(t, n);
for (int i = 1; i <= s; i++) {
if (aPow.equals(BigInteger.ONE)) {
break;
}
if (aPow.equals(n.subtract(BigInteger.ONE))) {
break;
}
BigInteger aPowSquared = aPow.multiply(aPow).mod(n);
if (aPowSquared.equals(BigInteger.ONE)) {
return aPow.subtract(BigInteger.ONE).gcd(n);
}
aPow = aPowSquared;
}
}
}