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
openss...@openssl.org
Automated List Manager
majo...@openssl.org