I have written AES encryption which uses salt int nrounds=5; unsigned char salt[]= {1,2,3,4, 5,6,7,8}; unsigned char key[32], iv[32];
unsigned char *key_data="password"; int key_data_len= 8; i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv); Sample code supplied for this. I am required to use Java to decrypt the openssl encrypted salted password AES so I wrote Java code to encrypt and decrypt using salt. I cannot figure out what are the parms for the salt to get the same results of encryption as I get with openssl. The "C" program which encrypts using openssl is shown along with the Java code that encrypts (and decrypts). This is the output of the Java program using password "porsche" and porsche for the string java AESjava password porsche Original: porsche 706F7273636865 Encrypted: 54D818BE067A1BCE0EE1320672576EEB Decrypted:porsche 706F7273636865 This is the output of the openssl code using password and porsche ./other password porsche AES_BLOCK_SIZE 16 MAX KEY LENGTH is 32 length in 7 Original: porsche 706F7273636865 length out 16 Encrypted: B667BEDBDA785A834A1FAD8F8958FC7B Obviously the encryption is different as the salt is not computed the same. Java verses the openssl encrypted result 54D818BE067A1BCE0EE1320672576EEB B667BEDBDA785A834A1FAD8F8958FC7B So if anyone out there should know what good parms to use for openssl and Java to encrypt using Salt for same results please let me know. I assume I can decrypt if same encrypt results. JAVA CODE ======== import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; public class AESjava { private static final int KEY_LENGTH = 128; private static final int ITERATIONS = 5; private static final String ALGORITHM = "AES"; private static final String SECRET_KEY_ALGORITHM = "PBKDF2WithHmacSHA1"; private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; private final Cipher m_enc_cipher; private final Cipher m_dec_cipher; public AESjava(final char[] password, final byte[] salt) throws Exception { // Derive the key, given password and salt final SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM); final KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS,KEY_LENGTH); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), ALGORITHM); // Build encryptor and get IV final Cipher enc_cipher = Cipher.getInstance(TRANSFORMATION); enc_cipher.init(Cipher.ENCRYPT_MODE, secret); // Build decryptor final Cipher dec_cipher = Cipher.getInstance(TRANSFORMATION); final AlgorithmParameters params = enc_cipher.getParameters(); final byte[] iv = params.getParameterSpec(IvParameterSpec.class) .getIV(); dec_cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); this.m_enc_cipher = enc_cipher; this.m_dec_cipher = dec_cipher; } public byte[] encrypt(final byte[] data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { return this.m_enc_cipher.doFinal(data); } public byte[] decrypt(final byte[] data) throws IllegalBlockSizeException, BadPaddingException { return this.m_dec_cipher.doFinal(data); } public static void test(String pass, String string) throws Exception{ final char[] password = pass.toCharArray(); final byte[] salt = new byte[] {1,2,3,4, 5,6,7,8}; final byte[] original_data = string.getBytes(); final AESjava aesA = new AESjava(password, salt); final byte[] encrypted_data = aesA.encrypt(original_data); System.out.println("Original: "+ string); System.out.println(javax.xml.bind.DatatypeConverter .printHexBinary(original_data) ); System.out.println(); System.out.println("Encrypted:"); System.out.println(javax.xml.bind.DatatypeConverter .printHexBinary(encrypted_data)); System.out.println(); final byte[] decrypted_data = aesA.decrypt(encrypted_data); System.out.println("Decrypted:"+new String(decrypted_data) ); System.out.println(javax.xml.bind.DatatypeConverter .printHexBinary(decrypted_data)); System.out.println(); } public static void main(final String[] args) { try { test(args[0], args[1]); } catch (Exception e){ e.printStackTrace(); } } } openssl code "C" ============ /** AES encryption/decryption demo program using OpenSSL EVP apis cc -o other -Wno-deprecated-declarations other.c -lcrypto **/ #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <openssl/evp.h> #include <openssl/aes.h> /** * Create an 256 bit key and IV using the supplied key_data. salt can be added for taste. * Fills in the encryption and decryption ctx objects and returns 0 on success **/ int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx) { int i, nrounds = 5; unsigned char key[32], iv[32]; /* * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material. * nrounds is the number of times the we hash the material. More rounds are more secure but * slower. */ i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv); if (i != 32) { printf("Key size is %d bits - should be 256 bits\n", i); return -1; } EVP_CIPHER_CTX_init(e_ctx); EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv); EVP_CIPHER_CTX_init(d_ctx); EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv); return 0; } /* * Encrypt *len bytes of data * All data going in & out is considered binary (unsigned char[]) */ unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len) { /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */ int c_len = *len + AES_BLOCK_SIZE, f_len = 0; unsigned char *ciphertext = malloc(c_len); /* allows reusing of 'e' for multiple encryption cycles */ EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL); /* update ciphertext, c_len is filled with the length of ciphertext generated, *len is the size of plaintext in bytes */ EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len); /* update ciphertext with the final remaining bytes */ EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len); *len = c_len + f_len; return ciphertext; } /* * Decrypt *len bytes of ciphertext */ unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len) { /* because we have padding ON, we must allocate an extra cipher block size of memory */ int p_len = *len, f_len = 0; unsigned char *plaintext = malloc(p_len + AES_BLOCK_SIZE); EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL); EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len); EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len); *len = p_len + f_len; return plaintext; } void help(){ printf("\n"); printf("Usage password word\n"); printf("eg:\n"); printf(" encryptAES256 password porsche\n\n"); } int main(int argc, char **argv) { /* "opaque" encryption, decryption ctx structures that libcrypto uses to record status of enc/dec operations */ EVP_CIPHER_CTX en, de; /* 8 bytes to salt the key_data during key generation. This is an example of compiled in salt. We just read the bit pattern created by these two 4 byte integers on the stack as 64 bits of contigous salt material - ofcourse this only works if sizeof(int) >= 4 */ unsigned char salt[]= {1,2,3,4, 5,6,7,8}; unsigned char *key_data; int key_data_len, i; if (argc<3){ help(); return 1; } printf("AES_BLOCK_SIZE %d \n",AES_BLOCK_SIZE); /* the key_data is read from the argument list */ key_data = (unsigned char *)argv[1]; key_data_len = strlen(argv[1]); printf("MAX KEY LENGTH is %d\n",EVP_MAX_KEY_LENGTH); if (key_data_len>EVP_MAX_KEY_LENGTH) key_data_len=EVP_MAX_KEY_LENGTH; /* gen key and iv. init the cipher ctx object */ if (aes_init(key_data, key_data_len, (unsigned char *)&salt, &en, &de)) { printf("Couldn't initialize AES cipher\n"); return -1; } char *plaintext; unsigned char *ciphertext; int length=0; unsigned char *result; unsigned char *p= (unsigned char *) argv[2]; length = strlen(argv[2]); printf("length in %d \n",length); printf("Original: %s\n",(char *)p); int a; for (int i=0; i<length; i++){ a= 0x00FF&p[i]; printf("%0X",a); } printf("\n\n"); ciphertext = aes_encrypt(&en, p, &length); printf("length out %d \n",length); printf("Encrypted:\n"); for (int i=0; i<length; i++){ a= 0x00FF&ciphertext[i]; printf("%0X",a); } printf("\n\n"); EVP_CIPHER_CTX_cleanup(&en); EVP_CIPHER_CTX_cleanup(&de); free(ciphertext); return 0; } -- View this message in context: http://old.nabble.com/AES-encryption-openssl-salt-and-Doing-it-in-Java-salt-tp34629647p34629647.html Sent from the OpenSSL - User mailing list archive at Nabble.com. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org