解密是在用3DES加密的Java Python中的数据(Decrypting data in Pyt

2019-09-01 02:02发布

我试图解密使用PyCrypto数据。 该数据被编码在Java中使用的javax.crypto包。 加密是三重DES(称为“ DESede ”在Java中)。 据我所知,用于一切默认设置。 然而,当我去解密在Python中的数据始终存在的数据有问题。

下面是不加密/解密的Java代码:

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.spec.KeySpec;

public final class Encrypter
{
    public static final String DESEDE_ENCRYPTION = "DESede";

    private KeySpec keySpec;
    private SecretKeyFactory keyFactory;
    private Cipher cipher;

    private static final String UNICODE_FORMAT = "UTF8";

    public Encrypter(String encryptionKey)
        throws Exception
    {
        byte[] keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
        keySpec = new DESedeKeySpec(keyAsBytes);
        keyFactory = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION);
        cipher = Cipher.getInstance(DESEDE_ENCRYPTION);
    }

    public String encryptString(String unencryptedString)
    {
        SecretKey key = keyFactory.generateSecret(keySpec);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] cleartext = unencryptedString.getBytes(UNICODE_FORMAT);
        byte[] ciphertext = cipher.doFinal(cleartext);

        BASE64Encoder base64encoder = new BASE64Encoder();
        return base64encoder.encode(ciphertext);
    }

    public String decryptString(String encryptedString)
    {
        SecretKey key = keyFactory.generateSecret(keySpec);
        cipher.init(Cipher.DECRYPT_MODE, key);
        BASE64Decoder base64decoder = new BASE64Decoder();
        byte[] ciphertext = base64decoder.decodeBuffer(encryptedString);
        byte[] cleartext = cipher.doFinal(ciphertext);

        return bytesToString(cleartext);
    }

    private static String bytesToString(byte[] bytes)
    {
        StringBuilder sb = new StringBuilder();
        for (byte aByte : bytes)
        {
            sb.append((char) aByte);
        }
        return sb.toString();
    }
}

但是,当我走,是由这个代码生成的base64编码字符串中的一个,我不能解码。 下面是一些Python代码我试过的例子:

from Crypto.Cipher import DES3
import array

key = <value of the key, as a hex string>
encryptedvalue = <the value that's encrypted, as a string>
keyarray = array.array('B', key.decode("hex"))
des = DES3.new(keyarray)
value = des.decrypt(encryptedvalue.decode('base64'))

value.decode('utf-8') # Gives me an error

我已经得到了错误已经沿着线看

UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte

这意味着,沿途某处,我还没有得到的东西正确设置。 我一直工作在这几个小时,甚至去,至于试图寻找到了SunJCE源代码 ,这实现了DESede ,看看他们使用什么违约,但无济于事。 我将使用这个作为一个自动运行的脚本的一部分,所以我真的宁可不要用Java做我的解密。 有谁知道我需要做的正确解密我的数据?

Answer 1:

我不得不这样做,使之工作就是改变这一行

keyarray = array.array('B', key.decode("hex"))

为此:

keyarray = array.array('B', key.encode("utf-8"))

这种匹配Java是编码的关键,让我有正确的加密密钥的方式。


如果你来到这里希望从这个问题学习的东西,这里的一些一般性的建议:

  1. 仔细检查你的假设:密钥字符串是一个十六进制字符串,所以我认为它被用作这样的。
  2. 确保你知道你的假设是什么:我不自觉地去想我是如何做的是如何使用的关键假设。 这往往是在编程和使用寿命一般很常见的问题。
  3. 检查所有沿途的( 尤其是当你有一个值的Oracle ):在字节数组望着值是什么促使我实现我的问题。


文章来源: Decrypting data in Python that was encrypted in 3DES by Java