我的代码有问题,当我加密数据时,例如,在这种情况下,我用接收者的公钥加密的simmetric密钥,然后保存到文本文件,当我读取该文本文件并尝试解密时,使用接收者的私钥,我得到一个不同的密钥,因此我不能用它来解密加密的消息.
发件人的代码:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.security.KeyStore; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; class Sender{ public static void main(String[] args) { //infile.txt File inFile = new File(args[0]); //outfile.txt File outFile = new File(args[1]); //mykeystore.jks File keyStoreFile = new File(args[2]); //mykeystore info String alias = args[3]; String password = args[4]; String storepass = args[5]; //receptor certificate String receptorCert = args[6]; try { //Read plain text FileInputStream rawDataFromFile = new FileInputStream(inFile); byte[] plainText = new byte[(int) inFile.length()]; rawDataFromFile.read(plainText); //Create simmetric key String key = "Bar12345Bar12345"; // 128 bit key String initVector = "RandomInitVector"; // 16 bytes IV IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); //Encrypt plaintext byte[] ciphertext = cipher.doFinal(plainText); //Hash plaintext MessageDigest md = MessageDigest.getInstance("SHA"); md.update(plainText); byte[] digest = md.digest(); //Encrypt simmetric key with receiver's public key Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); PublicKey receptorPublicKey = getPublicKeyFromCert(receptorCert); rsaCipher.init(Cipher.ENCRYPT_MODE, receptorPublicKey); byte[] simmetricKey = rsaCipher.doFinal(skeySpec.getEncoded()); //Encrypt hash with my private key KeyStore myKeyStore = KeyStore.getInstance("JKS"); FileInputStream inStream = new FileInputStream(keyStoreFile); myKeyStore.load(inStream, storepass.toCharArray()); PrivateKey privatekey = (PrivateKey) myKeyStore.getKey(alias, password.toCharArray()); rsaCipher.init(Cipher.ENCRYPT_MODE, privatekey); byte[] encodedHash = rsaCipher.doFinal(digest); //Write to outputfile FileOutputStream outToFile = new FileOutputStream(outFile); outToFile.write(simmetricKey); outToFile.write(encodedHash); outToFile.write(ciphertext); outToFile.close(); rawDataFromFile.close(); } catch (Exception e) { e.printStackTrace(); e.getMessage(); } } public static PublicKey getPublicKeyFromCert(String certLocation) { PublicKey pub = null; try { InputStream inStream = new FileInputStream(certLocation); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream); inStream.close(); pub = (PublicKey) cert.getPublicKey(); } catch (Exception e) { e.printStackTrace(); } return pub; } }
接收者代码:
import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class Receiver { public static void main(String[] args) { //Sender's out file File inFile = new File(args[0]); //receiver's keystore File keyStoreFile = new File(args[1]); //receiver's keystore info String password = args[2]; String alias = args[3]; String storepass = args[4]; //sender's cetificate File cert = new File(args[5]); try { //get Sender's out file FileInputStream rawDataFromFile = new FileInputStream(inFile); byte[] simmetricKey = new byte[256]; byte[] hash = new byte[256]; byte[] message; rawDataFromFile.read(simmetricKey); rawDataFromFile.read(hash); int b = rawDataFromFile.available(); message = new byte[b]; rawDataFromFile.read(message); //decrypt the simmetric key with receiver's private key KeyStore myKeyStore = KeyStore.getInstance("JKS"); FileInputStream inStream = new FileInputStream(keyStoreFile); myKeyStore.load(inStream, storepass.toCharArray()); PrivateKey privatekey = (PrivateKey) myKeyStore.getKey(alias, password.toCharArray()); // Cipher deCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); deCipher.init(Cipher.DECRYPT_MODE, privatekey); byte[] key = deCipher.doFinal(simmetricKey); System.out.println(Base64.encodeBase64String(key)); } catch (Exception e) { System.out.println("Error del sistema " + e); e.printStackTrace(); } } }
更新:
现在我可以使用接收者的私钥解密simmetric密钥.但是当我加密消息时,我不知道如何使用相同的参数创建解码器.
发件人加密纯文本的代码.
String key = "Bar12345Bar12345"; // 128 bit key String initVector = "RandomInitVector"; // 16 bytes IV IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); System.out.println(iv.getIV()); SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] ciphertext = cipher.doFinal(plainText);
接收者的解密1
SecretKeySpec keySpec = new SecretKeySpec(decryptedKeySpec, "AES"); Cipher decoder = Cipher.getInstance("AES"); decoder.init(Cipher.DECRYPT_MODE, keyspec); byte[] original = descipher.doFinal(message);
错误:给定最后一块没有正确填充
接收者的解密2
SecretKeySpec keySpec = new SecretKeySpec(decryptedKeySpec, "AES"); Cipher decoder = Cipher.getInstance("AES/CBC/PKCS5PADDING"); decoder.init(Cipher.DECRYPT_MODE, keyspec); byte[] original = descipher.doFinal(message);
错误:参数丢失
最后更新: 现在我的代码工作,感谢所有的帮助.这段代码可以从这里下载(顺便说一下,它是西班牙语,但我觉得不重要):
下载
问题是您使用AES加密
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8")," AES "); 密码密码= Cipher.getInstance(" AES/CBC/PKCS5PADDING");
而要破译,你使用的是RSA,
Cipher deCipher = Cipher.getInstance(" RSA/ECB/PKCS1Padding");
使用AES进行加密/解密的代码段
import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; public class EncryptionDecryptionAES { static Cipher cipher; public static void main(String[] args) throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); SecretKey secretKey = keyGenerator.generateKey(); cipher = Cipher.getInstance("AES"); String plainText = "AES Symmetric Encryption Decryption"; System.out.println("Plain Text Before Encryption: " + plainText); String encryptedText = encrypt(plainText, secretKey); System.out.println("Encrypted Text After Encryption: " + encryptedText); String decryptedText = decrypt(encryptedText, secretKey); System.out.println("Decrypted Text After Decryption: " + decryptedText); } public static String encrypt(String plainText, SecretKey secretKey) throws Exception { byte[] plainTextByte = plainText.getBytes(); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encryptedByte = cipher.doFinal(plainTextByte); Base64.Encoder encoder = Base64.getEncoder(); String encryptedText = encoder.encodeToString(encryptedByte); return encryptedText; } public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception { Base64.Decoder decoder = Base64.getDecoder(); byte[] encryptedTextByte = decoder.decode(encryptedText); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decryptedByte = cipher.doFinal(encryptedTextByte); String decryptedText = new String(decryptedByte); return decryptedText; } }
请查看http://javapapers.com/java/java-symmetric-aes-encryption-decryption-using-jce/