简体   繁体   English

密码解密错误结果

[英]Cipher decrypt wrong result

For some reason I can not get cipher to decrypt correctly.由于某种原因,我无法正确解密密码。

If I run encrypt/decrypt code in one iteration, decrypt works.如果我在一次迭代中运行加密/解密代码,解密工作。 If I however encrypt a string, then run program again with that encrypted string, decription is wrong.但是,如果我加密一个字符串,然后使用该加密字符串再次运行程序,则描述是错误的。

private final String CIPHER_ALGHORITM = "AES/CTR/NoPadding";

private final String KEY_ALGHORITM = "AES";

private Cipher cipher;

private Key key;

private static Ciphering ciphering;

public static Ciphering get() {
    if (ciphering == null) ciphering = new Ciphering();
    return ciphering;
}

public static void main(String[] args) {
    String input = "test123456789test123456789";
    String encrypted = get().encrypt(input);
    System.out.println(encrypted);
    String decrypted = get().decrypt("96BnAtmlkC49gj4p3/2azkRH6JhufRQ851k=");
    System.out.println(decrypted);
}

private Ciphering() {
    try {
        this.cipher = Cipher.getInstance(CIPHER_ALGHORITM);
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGHORITM);
        keyGenerator.init(256);
        key = keyGenerator.generateKey();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }
}

public byte [] encrypt(byte [] data) {
    return performOp(Cipher.ENCRYPT_MODE, data, key);
}

public String encrypt(String string) {
    return Base64.getEncoder().encodeToString(encrypt(string.getBytes()));
}

public byte [] decrypt(byte [] data) {
    return performOp(Cipher.DECRYPT_MODE, data, key);
}

public String decrypt(String string) {
    return new String(decrypt(Base64.getDecoder().decode(string)));
}

private byte [] performOp(int opmode, byte [] data, Key key) {
    byte [] result = new byte[] {};

    try {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[16]);
        cipher.init(opmode, key, ivParameterSpec);
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }

    try {
        result = cipher.doFinal(data);
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    }

    return result;
}

note hardcoded value in decrypt() in Main.注意 Main 中decrypt()中的硬编码值。 That is a result from encrypt() method from previous iteration.这是来自上一次迭代的encrypt()方法的结果。 result is: # ? r z EX > z ѧ which is obviously incorrect.结果是: # ? r z EX > z ѧ ,这显然是不正确的。

However, main method:但是,主要方法:

String input = "test123456789test123456789";
String encrypted = get().encrypt(input);
System.out.println(encrypted);
String decrypted = get().decrypt(encrypted);
System.out.println(decrypted);

Gives me a correct result.给我一个正确的结果。

What am I missing here?我在这里缺少什么? Or am going about this (encrypting string) completely wrong?或者正在处理这个(加密字符串)完全错误? I admit I'm not very familiar with encryption or java Cipher.我承认我对加密或 java Cipher 不是很熟悉。

You are generating a new key every time you run the program.每次运行程序时都会生成一个新密钥。 It works when you decrypt the result of the current run, because you haven't changed the key.当您解密当前运行的结果时它会起作用,因为您没有更改密钥。 But the ciphertext from a previous run can't be decrypted because you no longer have the key.但是无法解密之前运行的密文,因为您不再拥有密钥。

Randomly generated keys like these are most commonly exchanged with the message recipient using an additional layer of encryption.像这样随机生成的密钥最常使用额外的加密层与消息接收者交换。 You'd make sure you have the authentic public key of the intended recipient (which may be yourself) and encrypt the AES key with that using the RSA algorithm.您将确保您拥有预期收件人(可能是您自己)的真实公钥,并使用 RSA 算法使用该公钥加密 AES 密钥。 Later, when the message is to be decrypted, the AES key can be recovered with the RSA private key.稍后,当要解密消息时,可以使用 RSA 私钥恢复 AES 密钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM