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

Reply via email to