RE: java to openssl
> From: owner-openssl-us...@openssl.org On Behalf Of Philip R. Landreth > Sent: Thursday, 12 January, 2012 09:33 > I was sent 2 files and a partial java code that another company uses to decrypt. > byte[] encryptedData = (byte[])msg.getBody().get(); > byte[] decryptionKey = readFileContents("/keyfile_3des"); > final SecretKey key = new SecretKeySpec(decryptionKey, "DESede"); > _log.debug("Creating Cipher ..."); > final IvParameterSpec iv = new IvParameterSpec(new byte[8]); > final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); > decipher.init(Cipher.DECRYPT_MODE, key, iv); > _log.debug("Performing Decryption ..."); > final byte[] decryptedData = decipher.doFinal(encryptedData); > I am trying to get the same result with decrypting in openssl > $ openssl enc -d -kfile keyfile_3des.txt -in encrypt.20120109.16.txt > -out test1.txt -des-ede-cbc -nosalt > I thought that the default padding for openssl was pkcs5 but I get > what seems to me to be a padding error > bad decrypt > 140735237683644:error:06065064:digital envelope routines: > EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:467: The 'enc' utility normally does *password based encryption* which derives the actual cipher key by a complicated hashing process. -kfile takes the *password* from a file, not the actual key. The only option that takes an actual key is -K and it doesn't read from a file, so you'll have to get the key bytes, convert to hex, and pass them to -K. Which may be insecure on an OS where other processes can see process args, if anyone else can run programs. With -K you must give -iv explicitly, also in hex; that Java code is using 8 bytes of zero for the IV (which substantially reduces the security benefit the IV is intended to provide) so you must also. Alternatively write your own code which just calls the DES_ routines directly or the EVP_Decrypt* routines with cipher=EVP_des_ede3_cbc(). It's probably about 20-40 lines as a standalone program (depending on what options you need/want) or less as a function you integrate into an existing program that uses the result if there is such. PKCS5 is indeed the default for EVP_ and 'enc'; for DES_ you have to code it yourself, but it's only a few lines even at most careful. This shows up as a padding error because the raw decrypt operation with the wrong key produces effectively random garbage, and the first thing that looks at that data is the remove-padding operation which says "hey, this is garbage, I can't do squat with it". With -nopad you should still get garbage, it just isn't detected as such. I'm also concerned that your filename is ".txt". If it is readable (e.g. all or nearly all alphanumeric) then it is (with overwhelming probability) not the actual ciphertext, rather an 'armoring' such as commonly used base64 or hex. If it is (only) base64 the 'enc' utility can handle that with -a and maybe -A; for hex or other you must decode it yourself before passing in (which you can do on standard input); and for your own program you need to do either or whatever. If the data is actually binary and you just named it ".txt" it *might* be just the ciphertext, or it might be some other format that *includes* the ciphertext, such as PKCS7/CMS DER. Or HTTP-kindof-MIME. Or XML. Or who knows. msg.getBody().get() suggests to me that there is some logic involved in getting the ciphertext out of the message, but you'll have to find out what that consists of. The cast also worries me; AFAICS the only other Java type than can be cast to byte[] is Object, and an API for .get() that does that would be pretty weird. (Array-of-object types can be elementally-upcast, but not array-of-primitive which are implemented differently and have no up, or vice versa.) If you find out this cast is not redundant and useless, I'd be curious. You also have .txt on the keyfile and readFileContents(keyfile) might be doing something other than just reading the bytes, although here the name is not so suggestive to me. If it is, you need to do whatever that reading process is in the argument to enc -K, or in your own code. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org
RE: java to openssl
Thank you for your help! The files were given to me in .txt format and the original file is a .txt. as for the "keyfile" being in .txt I don't know. I used -p to print the key and iv and used those instead of using -kfile. iv did not print as 8 zeros either it prints a 16 digit alpha numberic. The encrypted file .txt is not readable(not alpha numeric) also when I add -a it will output a blank .txt file. Thank you for your help again. Philip Landreth -Original Message- From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] On Behalf Of Dave Thompson Sent: Thursday, January 12, 2012 6:58 PM To: openssl-users@openssl.org Subject: RE: java to openssl > From: owner-openssl-us...@openssl.org On Behalf Of Philip R. Landreth > Sent: Thursday, 12 January, 2012 09:33 > I was sent 2 files and a partial java code that another company uses to decrypt. > byte[] encryptedData = (byte[])msg.getBody().get(); > byte[] decryptionKey = readFileContents("/keyfile_3des"); > final SecretKey key = new SecretKeySpec(decryptionKey, "DESede"); > _log.debug("Creating Cipher ..."); > final IvParameterSpec iv = new IvParameterSpec(new byte[8]); > final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); > decipher.init(Cipher.DECRYPT_MODE, key, iv); > _log.debug("Performing Decryption ..."); > final byte[] decryptedData = decipher.doFinal(encryptedData); > I am trying to get the same result with decrypting in openssl > $ openssl enc -d -kfile keyfile_3des.txt -in encrypt.20120109.16.txt > -out test1.txt -des-ede-cbc -nosalt > I thought that the default padding for openssl was pkcs5 but I get > what seems to me to be a padding error > bad decrypt > 140735237683644:error:06065064:digital envelope routines: > EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:467: The 'enc' utility normally does *password based encryption* which derives the actual cipher key by a complicated hashing process. -kfile takes the *password* from a file, not the actual key. The only option that takes an actual key is -K and it doesn't read from a file, so you'll have to get the key bytes, convert to hex, and pass them to -K. Which may be insecure on an OS where other processes can see process args, if anyone else can run programs. With -K you must give -iv explicitly, also in hex; that Java code is using 8 bytes of zero for the IV (which substantially reduces the security benefit the IV is intended to provide) so you must also. Alternatively write your own code which just calls the DES_ routines directly or the EVP_Decrypt* routines with cipher=EVP_des_ede3_cbc(). It's probably about 20-40 lines as a standalone program (depending on what options you need/want) or less as a function you integrate into an existing program that uses the result if there is such. PKCS5 is indeed the default for EVP_ and 'enc'; for DES_ you have to code it yourself, but it's only a few lines even at most careful. This shows up as a padding error because the raw decrypt operation with the wrong key produces effectively random garbage, and the first thing that looks at that data is the remove-padding operation which says "hey, this is garbage, I can't do squat with it". With -nopad you should still get garbage, it just isn't detected as such. I'm also concerned that your filename is ".txt". If it is readable (e.g. all or nearly all alphanumeric) then it is (with overwhelming probability) not the actual ciphertext, rather an 'armoring' such as commonly used base64 or hex. If it is (only) base64 the 'enc' utility can handle that with -a and maybe -A; for hex or other you must decode it yourself before passing in (which you can do on standard input); and for your own program you need to do either or whatever. If the data is actually binary and you just named it ".txt" it *might* be just the ciphertext, or it might be some other format that *includes* the ciphertext, such as PKCS7/CMS DER. Or HTTP-kindof-MIME. Or XML. Or who knows. msg.getBody().get() suggests to me that there is some logic involved in getting the ciphertext out of the message, but you'll have to find out what that consists of. The cast also worries me; AFAICS the only other Java type than can be cast to byte[] is Object, and an API for .get() that does that would be pretty weird. (Array-of-object types can be elementally-upcast, but not array-of-primitive which are implemented differently and have no up, or vice versa.) If you find out this cast is not redundant and useless, I'd be curious. You also have .txt on the keyfile and readF
RE: java to openssl
> From: owner-openssl-us...@openssl.org On Behalf Of Philip R. Landreth > Sent: Friday, 13 January, 2012 09:55 > The files were given to me in .txt format and the original file is a > .txt. as for the "keyfile" being in .txt I don't know. I used -p to > print the key and iv and used those instead of using -kfile. > iv did not > print as 8 zeros either it prints a 16 digit alpha numberic. The > encrypted file .txt is not readable(not alpha numeric) also when I add > -a it will output a blank .txt file. > You seem to have confused unrelated things, perhaps because I answered several questions. Let me try in pieces. One preliminary: The Java code you posted used the "contents" of keyfile_3des as the cipher key. First you need to know if readFileContents does anything other more complicated than its name says. One simple thing is to check the file size: if 24 bytes it is almost certainly a true "3key 3DES" key; if 16 bytes it is most likely a "2key 3DES" key (which you turn into a true 3DES key by duplicating K1); if anything else you'll have to find out what the file contains, and what part(s) of it are the actual key to use. The main point: OpenSSL 'enc' normally does password based encryption (PBE). PBE does *not* use the supplied password, even though it is sometimes called a key, as the key. It *derives* the actual key and IV *from* the password, plus the salt if used. If you do enc -k xyz or -kfile (contains-xyz) -nosalt etc. it uses a key and IV *derived from* xyz. If you add -p or -P it prints the *derived* key and IV in hex. These are *not* what the Java is using, and using them in OpenSSL will *not* give the same result as the Java. The Java uses the "contents" of the keyfile as the key *without* derivation, and it uses all zeros as the IV. If you want to do the same NON-PBE decryption with 'enc', you must use the "contents" of keyfile in hex with -K and eight 0s in hex with -iv. Hex uses 2 characters for each byte. A (true) 3DES key is 24 bytes and its IV is 8 bytes, but in hex they are 48 characters and 16 characters respectively, alphanumeric but restricted to 0-9 and A-F or a-f. Finally, the ciphertext (encrypted data): If the data file isn't (mostly) alphanumeric it isn't hex or base64 (and I said -a applies only if it's base64). But that doesn't confirm whether it is only the ciphertext or something that includes the ciphertext. As I said, msg.getBody().get() suggests there is more and only part of the file is the ciphertext, but you need to find out what that is, i.e. what .getBody() does; and also what .get() does but that sounds like it's probably simple. Then supply *that* data as -in or stdin to 'enc'. FWIW the only indexed JDK methods named getBody() are in java.net.CacheRequest java.net.CacheResponse and javax.xml.soap.SOAPEnvelope , and none of them returns a type that implements .get() , so this must be EE or similar or a third-party library or custom code. Using .txt for files that are not actually text or at least text-like tends to cause confusion, although it makes no difference to programs like OpenSSL. Unless something requires you to use particular names which are inaccurate, I suggest using accurate ones. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager majord...@openssl.org