I'm trying to decrypt data using PyCrypto. The data was encoded in Java with the javax.crypto package. The encryption is Triple DES (referred to as "DESede" in Java). As far as I can tell, default settings are used for everything. However, when I go to decrypt the data in Python there is always a problem with the data.
Here's the Java code that does encrypting/decrypting:
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();
}
}
But when I take one of the base64-encoded strings that was produced by this code, I can't decode it. Here's an example of some of the python code I've tried:
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
The errors I've gotten have looked along the lines of
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa7 in position 6: invalid start byte
Which means that somewhere along the way, I haven't gotten something set up correctly. I've been working on this for a few hours, even going so far as trying to look into the SunJCE source code, which implements DESede, to see what defaults they use, but to no avail. I'm going to be using this as part of a script that runs automatically, so I'd really rather not have to use Java to do my decryption. Does anyone know what I need to do to decrypt my data correctly?