我正在尝试使用PyCrypto解密数据。数据使用javax.crypto包在Java中编码。加密是Triple DES(在Java中称为“DESede”)。据我所知,默认设置用于一切。但是,当我在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 source code,implements DESede,看看他们使用什么默认值,但无济于事。我将使用它作为自动运行的脚本的一部分,所以我真的不必使用Java来进行解密。有谁知道我需要做些什么才能正确解密我的数据?
答案 0 :(得分:3)
我必须做的就是改变这条线
keyarray = array.array('B', key.decode("hex"))
到此:
keyarray = array.array('B', key.encode("utf-8"))
这与java编码密钥的方式相匹配,允许我拥有正确的加密密钥。
如果你来这里希望从这个问题中学到一些东西,这里有一些一般的建议: