我需要编写一个java代码,使用客户提供的私钥/公钥来加密/解密消息。 这是我做的:
我从客户处获得了PKCS#1格式的私钥(以----- BEGIN RSA私钥-----开头)
我使用以下命令将其转换为PKCS#8:
openssl pkcs8 -topk8 -nocrypt -in private_pkcs1.key -out private_pkcs8.key
现在我拥有PKCS#8格式的私钥(以----- BEGIN PRIVATE KEY -----开头)
我使用以下命令从私钥中提取公钥(使用两种格式尝试,并获得相同的公钥):
openssl rsa -in private_pkcs8.key -pubout > public.key
我编写了以下方法来读取private_pkcs8.key文件的私钥:
private static PrivateKey readPrivateKey(String filename) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
File file = new File(filename);
FileInputStream in = new FileInputStream(file);
byte[] keyBytes = new byte[ new Long(file.length()).intValue() ];
in.read(keyBytes);
in.close();
String strPrivateKey = new String(keyBytes, "UTF-8").replaceAll("(-+BEGIN PRIVATE KEY-+\\r?\\n|-+END PRIVATE KEY-+\\r?\\n?)", "");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(DatatypeConverter.parseBase64Binary(strPrivateKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
我已经编写了以下方法来从public.key文件中读取公钥
private static PublicKey readPublicKey(String filename) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException
{
File file = new File(filename);
FileInputStream in = new FileInputStream(file);
byte[] keyBytes = new byte[ new Long(file.length()).intValue() ];
in.read(keyBytes);
in.close();
String strPublicKey = new String(keyBytes, "UTF-8").replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(DatatypeConverter.parseBase64Binary(strPublicKey));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
我写了以下加密方法
private static byte[] encrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException
{
Cipher cipher = Cipher.getInstance(ALGORITHEM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(message);
}
我写了以下解密方法
private static byte[] decrypt(byte[] message, Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException
{
Cipher cipher = Cipher.getInstance(ALGORITHEM);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(message);
}
我编写了以下主要测试应用程序,它试图加密一个简单的字符串并将其解密。
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, SignatureException, NoSuchProviderException, InvalidAlgorithmParameterException
{
readKeys();
String messageToEncrypt = "This is the string I want to test";
log("Original Message: " + messageToEncrypt);
byte[] originalBytes = messageToEncrypt.getBytes("UTF-8");
byte[] encriptedBytes = encrypt(originalBytes, privateKey);
byte[] decriptedMessage = decrypt(encriptedBytes, publicKey);
log("Decripted Message: " + new String(decriptedMessage));
}
加密没问题,但当我尝试将其解密回原始邮件时,我遇到以下异常:
Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
at sun.security.rsa.RSAPadding.unpad(Unknown Source)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.company.encryption.utils.RsaUtils.decrypt(RsaUtils.java:95)
at com.company.encryption.utils.RsaUtils.main(RsaUtils.java:108)
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]
请注意,JVM也会崩溃,这很奇怪。
我在这个问题上花了2天多时间。我确保使用相同的公钥/私钥对,我没有尝试将byte []转换为String。我已经完成了所有事情"通过书#34;
我们将非常感谢您对此问题的任何帮助。是否有一些问题我可以问我的客户关于钥匙,这将帮助我解决这个谜?为什么JVM也会崩溃?
由于 Guy Hudara
答案 0 :(得分:0)
在非对称密码中,一个用公钥加密,用私钥解密。通过这种方式,它可以确保任何人都可以使用公知的公钥加密邮件,但只有私钥的持有者可以对其进行解密。
byte[] encryptedBytes = encrypt(originalBytes, publicKey);
byte[] decryptedBytes = decrypt(encryptedBytes, privateKey);
答案 1 :(得分:0)
我有同样的问题。通过重新生成公钥来解决。