【问题标题】:Java error in decryption解密中的Java错误
【发布时间】:2015-01-12 10:45:40
【问题描述】:

我有两个名为encryption.java 和decryption.java 的类。我想使用 encrypt.java 类加密文本文件并从 decrypt.java 类解密。我可以成功加密文本文件,但不能以同样的方式解密它。谁能告诉我为什么不呢?

这是 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);
 }

这是我的解密.java 类:

 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);  }}

解密类运行时出错,像这样

 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)

【问题讨论】:

标签: java encryption cryptography


【解决方案1】:

您使用SecretKey SecKey = KeyGen.generateKey() 生成用于加密的密钥,这很好,但是当您解密时您尝试使用一个新密钥,而不是您用来加密文本的那个。您需要保存您的密钥,以便使用它进行解密。

【讨论】:

    【解决方案2】:

    您需要存储此 SecretKey SecKey = KeyGen.generateKey(); 值并在 Encrypt 和 Decrypt 类之间共享它。 所以基本上你必须在加密和解密过程中使用相同的 SecKey。

    【讨论】:

    • 是的,我想我在两个课程中都使用了相同的 secKey 对吗?否则,请您用您的答案修改我的代码。
    • 否,因为这个 SecretKey SecKey = KeyGen.generateKey();总是在创建新的 SecretKey。看到这个寻求帮助:link
    【解决方案3】:

    在任何事情之前,我认为您应该阅读更多关于对称密码学here 的内容。正如您将注意到的,对称密码学的主要特征之一是它们相同密钥用于加密和解密。相比之下,非对称加密(或公钥加密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 = // 从文件中获取字符串 String [] key = serializedSecKey.split(";"); byte[] keyBytes = Base64.decodeBase64(key[0]); 字符串算法 = key[1]; SecretKey secKey = new SecretKeySpec(keyBytes, algorithm);

    并且获得的secKey 将能够解密您的消息。

    最后,请注意,这可能不是保留密钥的最佳方式。有更好的选择,例如 KeyStores,可以让所有这些共享变得更加容易。

    【讨论】:

      猜你喜欢
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 1970-01-01
      相关资源
      最近更新 更多