Java解密错误
Java error in decryption
我有两个 class,名字是 encryption.java 和 decryption.java。我想使用 encrypt.java class 加密文本文件并从 decrypt.java class 解密。我可以成功加密文本文件,但无法以同样的方式解密。谁能告诉我为什么不呢?
这是encrypt.java:
public class Encrypt{
public static void main(String[] args) throws Exception {
String FileName = "D:/ashok/normal.txt";
String FileName1 = "D:/ashok/encrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherText = Files.readAllBytes(Paths.get(FileName));
AesCipher.init(Cipher.ENCRYPT_MODE, SecKey);
byte[] byteCipherText = AesCipher.doFinal(cipherText);
Files.write(Paths.get(FileName1), byteCipherText);
}
这是我的 decrypt.java class:
class decrypt{
public static void main(String[] args) {
try {
String FileName1 = "D:/ashok/encrypted.txt";
String FileName2 = "D:/ashok/decrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherrText = Files.readAllBytes(Paths.get(FileName1));
AesCipher.init(Cipher.DECRYPT_MODE, SecKey);
byte[] bytePlainText = AesCipher.doFinal(cipherrText);
Files.write(Paths.get(FileName2), bytePlainText); }}
解密 class 运行时出错,像这样
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at decryption.main(decryption.java:79)
您使用 SecretKey SecKey = KeyGen.generateKey()
生成用于加密的密钥,这很好,但是当您解密时,您尝试使用新密钥,而不是用于加密文本的密钥。您需要保存您的密钥,以便您可以使用它来解密。
您需要存储此 SecretKey SecKey = KeyGen.generateKey();
值并在加密和解密 类 之间共享它。
所以基本上你必须在加密和解密过程中使用相同的 SecKey。
首先,我认为您应该阅读更多有关对称密码学的内容 here. As you will note, one of the main features of symmetric cryptography is that they same key is used to encrypt and decrypt. In contrast, asymmetric cryptography (or Public key cryptography link) 使用一对密钥:一个用于加密,另一个用于解密。
因此,您的问题是您应该坚持SecretKey SecKey
。例如,您可以将密钥保存在单独的文件中。为此,您需要 (a) 字节数组(密钥)和 (b) 算法。如何在 Encrypt 端执行此操作的示例可以是:
String serializedSecKey = new String(Base64.encodeBase64(masterSecretKey.getEncoded())) + ";" + masterSecretKey.getAlgorithm()
storeToFile(filename, serializedSecKey);
Base64.encodeBase64()
来自 org.apache.commons.codec.binary.Base64;
。请注意,我在 key 及其 algorithm 之间添加了一个分隔符以方便解析。
然后,在您的 Decrypt 端,您可以解析包含有关密钥信息的文件。重建密钥的示例是:
String serializedSecKey = // obtain the string from the file
String [] key = serializedSecKey.split(";");
byte[] keyBytes = Base64.decodeBase64(key[0]);
String algorithm = key[1];
SecretKey secKey = new SecretKeySpec(keyBytes, algorithm);
而获得的 secKey
将能够解密您的消息。
最后,请注意,这可能不是保存密钥的最佳方式。有更好的选项,例如 KeyStores,可以使所有这些共享变得更加容易。
我有两个 class,名字是 encryption.java 和 decryption.java。我想使用 encrypt.java class 加密文本文件并从 decrypt.java class 解密。我可以成功加密文本文件,但无法以同样的方式解密。谁能告诉我为什么不呢?
这是encrypt.java:
public class Encrypt{
public static void main(String[] args) throws Exception {
String FileName = "D:/ashok/normal.txt";
String FileName1 = "D:/ashok/encrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherText = Files.readAllBytes(Paths.get(FileName));
AesCipher.init(Cipher.ENCRYPT_MODE, SecKey);
byte[] byteCipherText = AesCipher.doFinal(cipherText);
Files.write(Paths.get(FileName1), byteCipherText);
}
这是我的 decrypt.java class:
class decrypt{
public static void main(String[] args) {
try {
String FileName1 = "D:/ashok/encrypted.txt";
String FileName2 = "D:/ashok/decrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherrText = Files.readAllBytes(Paths.get(FileName1));
AesCipher.init(Cipher.DECRYPT_MODE, SecKey);
byte[] bytePlainText = AesCipher.doFinal(cipherrText);
Files.write(Paths.get(FileName2), bytePlainText); }}
解密 class 运行时出错,像这样
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at decryption.main(decryption.java:79)
您使用 SecretKey SecKey = KeyGen.generateKey()
生成用于加密的密钥,这很好,但是当您解密时,您尝试使用新密钥,而不是用于加密文本的密钥。您需要保存您的密钥,以便您可以使用它来解密。
您需要存储此 SecretKey SecKey = KeyGen.generateKey();
值并在加密和解密 类 之间共享它。
所以基本上你必须在加密和解密过程中使用相同的 SecKey。
首先,我认为您应该阅读更多有关对称密码学的内容 here. As you will note, one of the main features of symmetric cryptography is that they same key is used to encrypt and decrypt. In contrast, asymmetric cryptography (or Public key cryptography link) 使用一对密钥:一个用于加密,另一个用于解密。
因此,您的问题是您应该坚持SecretKey SecKey
。例如,您可以将密钥保存在单独的文件中。为此,您需要 (a) 字节数组(密钥)和 (b) 算法。如何在 Encrypt 端执行此操作的示例可以是:
String serializedSecKey = new String(Base64.encodeBase64(masterSecretKey.getEncoded())) + ";" + masterSecretKey.getAlgorithm() storeToFile(filename, serializedSecKey);
Base64.encodeBase64()
来自 org.apache.commons.codec.binary.Base64;
。请注意,我在 key 及其 algorithm 之间添加了一个分隔符以方便解析。
然后,在您的 Decrypt 端,您可以解析包含有关密钥信息的文件。重建密钥的示例是:
String serializedSecKey = // obtain the string from the file String [] key = serializedSecKey.split(";"); byte[] keyBytes = Base64.decodeBase64(key[0]); String algorithm = key[1]; SecretKey secKey = new SecretKeySpec(keyBytes, algorithm);
而获得的 secKey
将能够解密您的消息。
最后,请注意,这可能不是保存密钥的最佳方式。有更好的选项,例如 KeyStores,可以使所有这些共享变得更加容易。