From: Arne Vajhøj on
Scooter wrote:
> You all have been really helpful so far, but honestly I'm swimming
> upstream here. I know very little about cryptography and I'm trying to
> learn but the light aint coming on yet.
>
> Here's the beginning of the C# code. I've been playing with
> KeyGenerator,SecretKey etc, but I'm not getting it. Plus I'm getting
> conflicting articles online about whether SHA256 is incorporated in
> java or not. Maybe they were all old.

MessageDigest md = MessageDigest.getInstance("SHA-256");

will give you SHA-256.

At least in newer Jav aversions. It may be missing in older
versions - in which case you will need to use BouncyCastele
to get it.

> I can't seem to find anything
> where you generate a key based off of your own strings like the C#
> code seems to be doing. Seems like keygenerator just generates a
> random one.

Cipher aes = Cipher.getInstance("AES");
aes.init(mode, new SecretKeySpec(key.getBytes("UTF-8"), "AES"));

will use the String key as key.

Arne
From: rossum on
On Tue, 18 Nov 2008 12:15:35 -0800 (PST), Scooter
<slbentley(a)gmail.com> wrote:

>You all have been really helpful so far, but honestly I'm swimming
>upstream here. I know very little about cryptography and I'm trying to
>learn but the light aint coming on yet.
>
>Here's the beginning of the C# code. I've been playing with
>KeyGenerator,SecretKey etc, but I'm not getting it. Plus I'm getting
>conflicting articles online about whether SHA256 is incorporated in
>java or not. Maybe they were all old. I can't seem to find anything
>where you generate a key based off of your own strings like the C#
>code seems to be doing. Seems like keygenerator just generates a
>random one. So, if you want to take the time and point me in the right
>direction, it would be very much appreciate.
>
>Anyway, I didn't write this, I'm just the lucky fella that has to try
>to convert it to java.
>
>RijndaelManaged objAesCipher = new RijndaelManaged();
> objAesCipher.KeySize = 256;
> objAesCipher.BlockSize = 128; // has to be 128 to be AES compat
> objAesCipher.Mode = CipherMode.CBC;
> objAesCipher.Padding = PaddingMode.PKCS7;
This part sets up the AES cypher in CBC mode with PKCS7 padding:

Cipher aesCrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
Cipher aesDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");

Standard Java does not implement PKCS7 padding, but has PKCS5, which
is identical.


> objAesCipher.Key = new System.Security.Cryptography.SHA256Managed
>().ComputeHash(
> new ASCIIEncoding().GetBytes("A Random String".ToLower())
> );
This part sets up a 256 byte key by hashing some text:

MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] aesKey = sha256.digest("A Random
String".toLowerCase().getBytes());


>
> byte[] fullSHA = new System.Security.Cryptography.SHA256Managed
>().ComputeHash(
> new ASCIIEncoding().GetBytes("3rfdfh6y-34rt-3rkl-9ijh-
>mg94kgjdhsg3".ToLower())
> );
>
> byte[] trimmedSHA = new byte[16];
>
> Array.Copy(fullSHA, trimmedSHA, 16);
This part sets up a 128 bit (16 byte) IV for CBC mode:

final int BLOCK_BYTES = 16;
sha256.reset();
byte[] fullSHA = sha256.digest("3rfdfh6y-34rt-3rkl-9ijh-
mg94kgjdhsg3".toLowerCase().getBytes());
byte[] aesIV = new byte[BLOCK_BYTES];
System.Arraycopy(fullSHA, 0, aesIV, 0, BLOCK_BYTES);

>
> // can only use 128 block size to be real AES
> objAesCipher.IV = trimmedSHA;
>
> m_objCrypt = objAesCipher.CreateEncryptor();
> m_objDecrypt = objAesCipher.CreateDecryptor();
This part sets up the IV and two cypher objects, one to encrypt and
one to decrypt:

IvParameterSpec aesParameterSpec = new IvParameterSpec(aesIV);
AlgorithmParameters aesParameters =
AlgorithmParameters.getInstance("AES");
aesParameters.init(aesParameterSpec);

aesCrypt.init(Cipher.ENCRYPT_MODE, aesKey, aesParameters);
aes.Decrypt.init(Cipher.DECRYPT_MODE, aesKey, aesParameters);

I have not compiled my code here, and I am more used to using Bouncy
Castle crypto than the Java standard crypto, so you may well need to
adjust what I have given you.

rossum

From: Scooter on
That works until the end. the Cipher.init method is expecting a type
"Key" or "Certificate" as the second parameter. I'm sort of back to
where I started in trying to figure out how a key is created based off
of my random string SHA256 HASH. Passing that byte array caused it to
choke. And again, thanks for the info provided so far.
From: Scooter on
I'm a step further now. I'm using the code from rossum but with some
updates to create a key from my string

....
//aesCrypt.init(Cipher.ENCRYPT_MODE, aesKey, aesParameters);
//aesDecrypt.init(Cipher.DECRYPT_MODE, aesKey, aesParameters);

SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey,
0,aesKey.length,"AES");
aesCrypt.init(Cipher.ENCRYPT_MODE, aesKeySpec, aesParameters);
aesDecrypt.init(Cipher.DECRYPT_MODE, aesKeySpec, aesParameters);

Doing that I get an "Illegal key size" exception

Do do I need to do this (and this again is going back to the code from
rossum):
byte[] aesKey = sha256.digest("A Random String".toLowerCase().getBytes
());
final int BLOCK_BYTES = 16;
byte[] padKey = new byte[BLOCK_BYTES];
System.arraycopy(aesKey,0,padKey,0,BLOCK_BYTES);
SecretKeySpec aesKeySpec = new SecretKeySpec(padKey,
0,padKey.length,"AES");

I'm asking because while that does eliminate the key size error, then
in my decryption I'm getting a padding error
but that could be something else

//yes I need to replace this with something other than sun.misc
//we base64encode or encrypted value so we need to decode it first
byte[] inputBuffer=new sun.misc.BASE64Decoder().decodeBuffer
(EncryptedValue);
//this throws 'Given final block not properly padded'
byte[] buffer = aesDecrypt.doFinal(inputBuffer,0,inputBuffer.length);











From: Arne Vajhøj on
Scooter wrote:
> I'm a step further now. I'm using the code from rossum but with some
> updates to create a key from my string
>
> ...
> //aesCrypt.init(Cipher.ENCRYPT_MODE, aesKey, aesParameters);
> //aesDecrypt.init(Cipher.DECRYPT_MODE, aesKey, aesParameters);
>
> SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey,
> 0,aesKey.length,"AES");
> aesCrypt.init(Cipher.ENCRYPT_MODE, aesKeySpec, aesParameters);
> aesDecrypt.init(Cipher.DECRYPT_MODE, aesKeySpec, aesParameters);
>
> Doing that I get an "Illegal key size" exception
>
> Do do I need to do this (and this again is going back to the code from
> rossum):
> byte[] aesKey = sha256.digest("A Random String".toLowerCase().getBytes
> ());
> final int BLOCK_BYTES = 16;
> byte[] padKey = new byte[BLOCK_BYTES];
> System.arraycopy(aesKey,0,padKey,0,BLOCK_BYTES);
> SecretKeySpec aesKeySpec = new SecretKeySpec(padKey,
> 0,padKey.length,"AES");
>
> I'm asking because while that does eliminate the key size error, then
> in my decryption I'm getting a padding error
> but that could be something else

AES expects keys in 128, 192 or 256 bits = 16, 24 or 32 bytes.

You need to give a key of that length.

I don't think it is optimal to pad with zero bytes and
I am also concerned that you could get an ArrayIndexOutOfBoundsException
with that code.

Your decryption error is due to something else.

Arne