[英]Using RSA encryption in Java without BouncyCastle
In my program, I'm trying to encrypt some plaintext with RSA using the following code: 在我的程序中,我正在尝试使用以下代码使用RSA加密某些明文:
static String RSAEncrypt(String pubkey, String plain){
return encrypt(pubkey,plain,"RSA");
}
static String encrypt(String stringKey, String plain, String algo){
String enc="failed";
try{
byte[] byteKey = new BASE64Decoder().decodeBuffer(stringKey);
Key key = new SecretKeySpec(byteKey,algo);
byte[] data = plain.getBytes();
Cipher c = Cipher.getInstance(algo);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(data);
enc = new BASE64Encoder().encode(encVal);
}catch(Exception e){e.printStackTrace();}
return enc;
}
However, when it runs, it shows the following error: 但是,当它运行时,它会显示以下错误:
java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec
at javax.crypto.Cipher.chooseProvider(Cipher.java:877)
at javax.crypto.Cipher.init(Cipher.java:1212)
at javax.crypto.Cipher.init(Cipher.java:1152)
at Crypto.encrypt(Crypto.java:37)
at Crypto.RSAEncrypt(Crypto.java:62)
I have tried changing it to RSA/None/PKCS1Padding and RSA/ECB/PKCS1Padding to no avail.. I know that installing BouncyCastle may help but I'd like to avoid it (I'd like to avoid more dependencies and I've been having some issues installing it anyway). 我已经尝试将其更改为RSA / None / PKCS1Padding和RSA / ECB / PKCS1Padding无济于事。我知道安装BouncyCastle可能有所帮助,但我想避免它(我想避免更多的依赖,我已经无论如何都要安装它的一些问题)。 Thanks in advance for any ideas. 提前感谢任何想法。
As was said in the comments, SecretKeySpec
is for symmetric algorithms only. 正如评论中所说, SecretKeySpec
仅用于对称算法。 You mentioned that you got your byte[]
containing the key by calling getEncoded
. 你提到你通过调用getEncoded
得到包含密钥的byte[]
。
There are two possibilities and two resulting formats: 有两种可能性和两种结果格式:
Calling PrivateKey#getEncoded
on an instance of an RSA private key will result in a PKCS#8 encoding for private keys, and it can be restored with the help of PKCS8EncodedKeySpec . 在RSA私钥的实例上调用PrivateKey#getEncoded
将导致私钥的PKCS#8编码,并且可以在PKCS8EncodedKeySpec的帮助下恢复。
PublicKey#getEncoded
on an RSA public key results in the generic X.509 public key encoding, and can be restored with X509EncodedKeySpec . RSA PublicKey#getEncoded
上的PublicKey#getEncoded
导致通用X.509公钥编码,可以使用X509EncodedKeySpec进行恢复。
byte[] data = "test".getBytes("UTF8");
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair keyPair = kpg.genKeyPair();
byte[] pk = keyPair.getPublic().getEncoded();
X509EncodedKeySpec spec = new X509EncodedKeySpec(pk);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(data);
byte[] priv = keyPair.getPrivate().getEncoded();
PKCS8EncodedKeySpec spec2 = new PKCS8EncodedKeySpec(priv);
PrivateKey privKey = keyFactory.generatePrivate(spec2);
cipher.init(Cipher.DECRYPT_MODE, privKey);
byte[] plain = cipher.doFinal(encrypted);
System.out.println(new String(plain, "UTF8")); //=> "test"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.