var*_*ara 7 java security encryption rsa
我被要求使用给定值modulus和exponent值生成RSA密钥.但我只想知道生成密钥而不指定模数和指数.无论我给出的值是什么,似乎都是大整数值.我在网上搜索了这个并制定了一些东西,但它无法通过成功.
所以,如果有人之前已经这样做了,他们可以给我一些提示吗?
这是我们尝试使用给定值的示例程序.
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
public class Sample {
public static void main( String args[] ) {
BigInteger modulus = new BigInteger("350871044328208704010580786055405681");
BigInteger exponent = new BigInteger("545161406957801571");
try {
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(spec);
PrivateKey priv = factory.generatePrivate(privateSpec);
System.out.println("Public Key : "+ byteArrayToHexString( pub.getEncoded() ));
System.out.println("Private Key : "+ byteArrayToHexString( priv.getEncoded() ));
}
catch( Exception e ) {
System.out.println(e.toString());
}
}
public static String byteArrayToHexString(byte[] bytes)
{
StringBuffer buffer = new StringBuffer();
for(int i=0; i<bytes.length; i++)
{
if(((int)bytes[i] & 0xff) < 0x10)
buffer.append("0");
buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buffer.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:RSA密钥长度必须至少为512位
alb*_*iff 11
我给你一些关于RSA的信息.首先在RSA中键入modulus = p·qwhere p和q不同的素数,模数长度就是它key length.所以当你收到例外时:
java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:RSA密钥长度必须至少为512位
这意味着您的模数至少必须为512位长.
除了在你的代码中还有另一个错误,你对公钥和私钥使用相同的指数,但这个指数必须是不同的数字.
在简历中,您必须java.math.BigInteger按照RSA密钥生成算法计算模数,公共指数和私有指数,以生成正确的密钥.我从你的代码中给你一个例子:
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
public class Sample {
public static void main( String args[] ) {
int keySize = 512;
SecureRandom random = new SecureRandom();
// Choose two distinct prime numbers p and q.
BigInteger p = BigInteger.probablePrime(keySize/2,random);
BigInteger q = BigInteger.probablePrime(keySize/2,random);
// Compute n = pq (modulus)
BigInteger modulus = p.multiply(q);
// Compute ?(n) = ?(p)?(q) = (p ? 1)(q ? 1) = n - (p + q -1), where ? is Euler's totient function.
// and choose an integer e such that 1 < e < ?(n) and gcd(e, ?(n)) = 1; i.e., e and ?(n) are coprime.
BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
BigInteger publicExponent = getCoprime(m,random);
// Determine d as d ? e?1 (mod ?(n)); i.e., d is the multiplicative inverse of e (modulo ?(n)).
BigInteger privateExponent = publicExponent.modInverse(m);
try {
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(modulus, privateExponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(spec);
PrivateKey priv = factory.generatePrivate(privateSpec);
System.out.println("Public Key : "+ byteArrayToHexString( pub.getEncoded() ));
System.out.println("Private Key : "+ byteArrayToHexString( priv.getEncoded() ));
}
catch( Exception e ) {
System.out.println(e.toString());
}
}
public static BigInteger getCoprime(BigInteger m, SecureRandom random) {
int length = m.bitLength()-1;
BigInteger e = BigInteger.probablePrime(length,random);
while (! (m.gcd(e)).equals(BigInteger.ONE) ) {
e = BigInteger.probablePrime(length,random);
}
return e;
}
public static String byteArrayToHexString(byte[] bytes)
{
StringBuffer buffer = new StringBuffer();
for(int i=0; i<bytes.length; i++)
{
if(((int)bytes[i] & 0xff) < 0x10)
buffer.append("0");
buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
}
return buffer.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有帮助,