我试图比较两个值,hcB已被散列,然后对值进行幂运算,hci正在做exp值的逆。然后比较。它们应该是平等的,但事实并非如此。
public class Hash
{
static MessageDigest sha1;
private static final int unitLength = 160; // SHA-1 has 160-bit output.
public static void main(String[] args)throws Exception
{
String s = new String("hello");
BigInteger b =new BigInteger(s.getBytes()); // Big integer conversion
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
sha1.reset();
sha1.update(s.getBytes());
byte[] hc = sha1.digest();
BigInteger hcB=new BigInteger(1,hc);
KeyGenerator keyRC=new KeyGenerator();
try {
keyRC.initialize();//generating key
BigInteger HashClValueExp=hcB.modPow(keyRC.RC, keyRC.p);// exponentiate of hashed value
System.out.println("HasheCldExp Value: "+HashClValueExp);
//Inverse RC
BigInteger inv = keyRC.RC.modInverse(keyRC.q);
System.out.println("Inverse RC: " + inv);
// Hash value inverse computation
BigInteger hci = HashClValueExp.modPow(inv, keyRC.p);
System.out.println("hci: " + hci); // prints in hex
System.out.println("hcB: " + hcB);
System.out.println("Compare hci and hcB :" + hci.compareTo(hcB));
} catch (Exception e) {
e.printStackTrace();
}
}
}
基本上要对N
的模幂求反你需要计算mod phi(N)
的逆。(非mod N
).
phi(N)
是N
中包含gcd(x, N) = 1
的元素的个数(换句话说,它们不共享任何素数因子)。如果你不知道N
的所有质因数,计算这个函数的值是很困难的N
的保理也不能(据我们所知)有效地完成。
这实际上是RSA-crypto-system的安全性所依赖的属性。
因此,为了使您的代码正常工作,您需要密钥生成器生成一组非常特定的值(我的示例显示了RSA加密所需的内容):
class RSAKey {
private final BigInteger p, q, e; // p and q must be distinct primes
public RSAKey(BigInteger p, BigInteger q, BigInteger e) {
this.p = p; this.q = q; this.e = e;
}
public BigInteger getN() { return p.multiply(q) } // return N
public BigInteger getE() { return e }; // return e
public BigInteger getPhiN() { // return phi(N)
return p.subtract(new BigInteger("1").multiply(q.subtract(new BigInteger("1")); // (p-1) * (q-1)
}
}
您的密钥生成器只需要生成两个随机质数p
和q
以及一个随机值e
,并将它们传递给上述类。
您编写的模求幂后跟反转的代码如下所示:
RSAKey key = keyGen.generateKey();
/*
* compute the decryption exponent d as:
* d = e^-1 mod phi(N)
*/
BigInteger d = key.getE().modInverse(key.getPhiN());
BigInteger c = m.modPow(e, N); // encrypt message m to ciphertext c
BigInteger m1 = c.modPow(d, N); // decrypt ciphertext c to message m1
System.out.println(m.equals(m1)); // the messages should be equal now
注:自己实现RSA仅用于教育目的!如果你想在其他地方使用rsa加密,您应该使用Java Cipher-类和Java KeyGenerator!