问题
We are migrating some code from perl to java/scala and we hit a roadblock.
We're trying to figure out how to do this in Java/scala:
use Crypt::CBC;
$aesKey = "some key"
$cipher = new Crypt::CBC($aesKey, "DES");
$encrypted = $cipher->encrypt("hello world");
print $encrypted // prints: Salted__�,%�8XL�/1�&�n;����쀍c
$decrypted = $cipher->decrypt($encrypted);
print $decrypted // prints: hello world
I tried a few things in scala but didn't really get it right, for example something like this:
val secretKey = new SecretKeySpec("some key".getBytes("UTF-8"), "DES")
val encipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
encipher.init(Cipher.ENCRYPT_MODE, secretKey)
val encrypted = encipher.doFinal(bytes)
println("BYTES:" + bytes)
println("ENCRYPTED!!!!!!: " + encrypted)
println(toString(encrypted))
Any help or direction in Java/scala would very much be appreciated
回答1:
Assuming that Crypt module is the one I find at https://metacpan.org/pod/Crypt::CBC it is documented as by default doing (the same as) openssl, apparently meaning commandline 'enc' (openssl library has MANY other options). That is not encryption with the specified key (and IV) directly, but instead 'password-based' encryption (PBE) with a key and IV derived from the specified 'key' (really passphrase) plus (transmitted) salt, using a twist on the original (now unrecommended) PKCS#5 v1.5 algorithm, retronymed PBKDF1. See http://www.openssl.org/docs/crypto/EVP_BytesToKey.html (or the man page on a Unix system with openssl installed) and rfc2898 (or the original RSA Labs PKCS documents now somewhere at EMC).
You say you cannot change the perl sender. I hope the users/owners/whoever realize that original DES, retronymed single-DES for clarity, has been practically brute-forceable for well over a decade, and PBE-1DES may be even weaker; the openssl twist doesn't iterate as PKCS#5 (both KDF1 and KDF2) should.
Java (with the Suncle providers) does implement PBEWithMD5AndDES, which initted with PBEParameterSpec (salt, 1) does successfully decrypt data from 'openssl enc -des-cbc', and thus I expect also your perl sender (not tested). FWIW if you could change to triple-DES, Java implements PBEWithMD5AndTripleDES using an apparently nonstandard extension of PBKDF1 (beyond hash size) that is quite unlike openssl's nonstandard extension, and thus incompatible if the perl module is in fact following openssl. You would have to do the key-derivation yourself and then direct 3DES-CBC-pad, which isn't very hard.
Also note encrypted data from any modern computer algorithm is binary. "Printing" it as if it were text in perl, or Java or nearly anything else, is likely to cause data corruption if you try to use it again. If you are only looking to see 'is there any output at all, and is it visibly not the plaintext' you're okay.
来源:https://stackoverflow.com/questions/22085107/perl-cbc-des-equivalent-in-java