Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Cryptography

Reply
Thread Tools

Cryptography

 
 
Scooter
Guest
Posts: n/a
 
      11-17-2008
I have been tasked with writing a small java class that will decrypt a
string that was encrypted with a C# app. I have the source for the C#
decryption, its nothing special. I just dont know what the
counterparts are in java.

Heres the C# code. "m_objDecrypt" is a "ICryptoTransform"

protected internal string DecryptValue(string EncryptedValue)
{
byte[] buffer;
if (EncryptedValue.Length >= 0x800)
{
throw new ValueException();
}
try
{
byte[] inputBuffer = Convert.FromBase64String(EncryptedValue);
buffer = this.m_objDecrypt.TransformFinalBlock(inputBuffer, 0,
inputBuffer.Length);
}
catch (FormatException)
{
throw new ValueException();
}
catch (CryptographicException)
{
throw new ValueException();
}
return new ASCIIEncoding().GetString(buffer);
}

--------------------------
in my java class so far I have:

byte[] buffer;

if (EncryptedValue.length() >= 0x800) {


}

try
{
byte[]inputBuffer=new sun.misc.BASE64Decoder().decodeBuffer
(EncryptedValue);
//buffer=
}
catch (Exception e)
{

}


I just have no idea about converting that whole "TransformFinalBlock"
method.

Any suggestions are appreciated.
 
Reply With Quote
 
 
 
 
Arne Vajhøj
Guest
Posts: n/a
 
      11-18-2008
Scooter wrote:
> I have been tasked with writing a small java class that will decrypt a
> string that was encrypted with a C# app. I have the source for the C#
> decryption, its nothing special. I just dont know what the
> counterparts are in java.
>
> Heres the C# code. "m_objDecrypt" is a "ICryptoTransform"
>
> protected internal string DecryptValue(string EncryptedValue)
> {
> byte[] buffer;
> if (EncryptedValue.Length >= 0x800)
> {
> throw new ValueException();
> }
> try
> {
> byte[] inputBuffer = Convert.FromBase64String(EncryptedValue);
> buffer = this.m_objDecrypt.TransformFinalBlock(inputBuffer, 0,
> inputBuffer.Length);
> }
> catch (FormatException)
> {
> throw new ValueException();
> }
> catch (CryptographicException)
> {
> throw new ValueException();
> }
> return new ASCIIEncoding().GetString(buffer);
> }
>
> --------------------------
> in my java class so far I have:
>
> byte[] buffer;
>
> if (EncryptedValue.length() >= 0x800) {
>
>
> }
>
> try
> {
> byte[]inputBuffer=new sun.misc.BASE64Decoder().decodeBuffer
> (EncryptedValue);
> //buffer=
> }
> catch (Exception e)
> {
>
> }
>
>
> I just have no idea about converting that whole "TransformFinalBlock"
> method.


The Java equivalent to C# ICryptoTransform.TransformFinalBlock is
Cipher.doFinal !

Attached below are some C# code and Java code that does the
same thing.

The use Hex not Base64 though.

Arne

===========================================

using System;
using System.Globalization;
using System.Text;
using System.Security.Cryptography;

namespace E
{
public class Program
{
public static string ToHex(byte[] ba)
{
StringBuilder sb = new StringBuilder(2 * ba.Length);
for(int i = 0; i < ba.Length; i++)
{
sb.Append(ba[i].ToString("X2"));
}
return sb.ToString();
}
public static byte[] FromHex(string s)
{
byte[] ba = new byte[s.Length/2];
for(int i = 0; i < ba.Length; i++)
{
ba[i] = byte.Parse(s.Substring(2 * i, 2),
NumberStyles.HexNumber);
}
return ba;
}
public static string Encrypt(string s)
{
TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
tdes.Key = Encoding.UTF8.GetBytes("MySecretKeyxxxxx");
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform crypt = tdes.CreateEncryptor();
byte[] plain = Encoding.UTF8.GetBytes(s);
byte[] cipher = crypt.TransformFinalBlock(plain, 0,
plain.Length);
return ToHex(cipher);
}
public static string Decrypt(string s)
{
TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
tdes.Key = Encoding.UTF8.GetBytes("MySecretKeyxxxxx");
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform crypt = tdes.CreateDecryptor();
byte[] cipher = FromHex(s);
byte[] plain = crypt.TransformFinalBlock(cipher, 0 ,
cipher.Length);
return Encoding.UTF8.GetString(plain);
}
public static void Main(string[] args)
{
string p1 = "Dette er en lille test ABC ÆØÅ 123 !!!!";
Console.WriteLine(p1);
string c = Encrypt(p1);
Console.WriteLine(c);
string p2 = Decrypt(c);
Console.WriteLine(p2);
}
}
}

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class TrippleDES {
static {
Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider ());
}
public static String encrypt(String s) throws
NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException, InvalidKeyException {
Cipher crypt = Cipher.getInstance("DESede/ECB/PKCS7Padding");
SecretKey key = new
SecretKeySpec("MySecretKeyxxxxx".getBytes(), "DESede");
crypt.init(Cipher.ENCRYPT_MODE, key);
byte[] plain = s.getBytes("UTF-8");
byte[] cipher = crypt.doFinal(plain, 0, plain.length);
return toHex(cipher);
}
public static String decrypt(String s) throws
NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException, InvalidKeyException {
Cipher crypt = Cipher.getInstance("DESede/ECB/PKCS7Padding");
SecretKey key = new
SecretKeySpec("MySecretKeyxxxxx".getBytes(), "DESede");
crypt.init(Cipher.DECRYPT_MODE, key);
byte[] cipher = fromHex(s);
byte[] plain = crypt.doFinal(cipher, 0, cipher.length);
return new String(plain, "UTF-8");
}
private static String toHex(byte[] ba) {
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < ba.length; i++) {
sb.append(Integer.toHexString((ba[i] >> 4) & 0x0F));
sb.append(Integer.toHexString(ba[i] & 0x0F));
}
return sb.toString();
}
private static byte[] fromHex(String s) {
int n = s.length() / 2;
byte[] res = new byte[n];
for(int i = 0; i < n; i++) {
res[i] = (byte)(Integer.parseInt(s.substring(2 * i, 2 * i +
2), 16));
}
return res;
}
public static void main(String[] args) throws Exception {
String p1 = "Dette er en lille test ABC ÆØÅ 123 !!!!";
System.out.println(p1);
String c = encrypt(p1);
System.out.println(c);
String p2 = decrypt(c);
System.out.println(p2);
}
}
 
Reply With Quote
 
 
 
 
Arne Vajhøj
Guest
Posts: n/a
 
      11-18-2008
rossum wrote:
> On Mon, 17 Nov 2008 11:58:47 -0800 (PST), Scooter
> <> wrote:
>> byte[]inputBuffer=new
>> sun.misc.BASE64Decoder().decodeBuffer(EncryptedVal ue);

> Do not use sun.misc for any production code, it cannot be relied on.


Good advice.

> Find a decent Base64 converter on the web (there are hundreds) and
> either copy or import that.


I would make that much more specific.

Do not find just any Base64 implementation.

Base64 is actually standardized in Java. It is just in
Java EE not in Java SE.

So find a standard compliant base64 implementation.

JavaMail reference implementation from SUN is one
possibility.

Some simple wrappers to make it easier to use:

public static String b64encode(byte[] b) throws MessagingException,
IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream b64os = MimeUtility.encode(baos, "base64");
b64os.write(b);
b64os.close();
return new String(baos.toByteArray());
}
public static byte[] b64decode(String s) throws
MessagingException, IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
InputStream b64is = MimeUtility.decode(bais, "Base64");
byte[] tmp = new byte[s.length()];
int n = b64is.read(tmp);
byte[] res = new byte[n];
System.arraycopy(tmp, 0, res, 0, n);
return res;
}

Arne
 
Reply With Quote
 
Scooter
Guest
Posts: n/a
 
      11-18-2008
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;
objAesCipher.Key = new System.Security.Cryptography.SHA256Managed
().ComputeHash(
new ASCIIEncoding().GetBytes("A Random String".ToLower())
);

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);

// can only use 128 block size to be real AES
objAesCipher.IV = trimmedSHA;

m_objCrypt = objAesCipher.CreateEncryptor();
m_objDecrypt = objAesCipher.CreateDecryptor();
 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      11-18-2008
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
 
Reply With Quote
 
Scooter
Guest
Posts: n/a
 
      11-19-2008
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.
 
Reply With Quote
 
Scooter
Guest
Posts: n/a
 
      11-19-2008
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.lengt h);











 
Reply With Quote
 
Arne Vajhøj
Guest
Posts: n/a
 
      11-19-2008
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
 
Reply With Quote
 
Scooter
Guest
Posts: n/a
 
      11-21-2008
I'm about to throw in the towel on this stuff. I think I just need to
sit down with a cryptography book..or someone that knows what their
doing. In testing my encryption values between c# and java I'm getting
different values.

Again here's the c# code :
protected internal ICryptoTransform m_objCrypt;
protected internal ICryptoTransform m_objDecrypt;

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;
objAesCipher.Key = new System.Security.Cryptography.SHA256Managed
().ComputeHash(new ASCIIEncoding().GetBytes("A Random String".ToLower
()));
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);
// can only use 128 block size to be real AES
objAesCipher.IV = trimmedSHA;
m_objCrypt = objAesCipher.CreateEncryptor();
m_objDecrypt = objAesCipher.CreateDecryptor();


protected internal String EncryptValue(String Value)
{

if (Value.Length >= MAX_QUERY_LENGTH)
{
throw new ValueException();
}

byte[] byaRawText = new System.Text.ASCIIEncoding().GetBytes
(Value);
byte[] byaCipherText = m_objCrypt.TransformFinalBlock(byaRawText,
0, byaRawText.Length);

return Convert.ToBase64String(byaCipherText);

}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heres my java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

protected static Cipher m_objCrypt;
protected static Cipher m_objDecrypt;



try {
m_objCrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
m_objDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MessageDigest sha256 = null;
try {
sha256 = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] aesKey = sha256.digest("A Random String".toLowerCase().getBytes
());
//printhash(aesKey);

// Sets up a 128 bit (16 byte) IV for CBC mode
final int BLOCK_BYTES = 16;
byte[] aesPaddedKey = new byte[BLOCK_BYTES];
System.arraycopy(aesKey,0,aesPaddedKey,0,BLOCK_BYT ES);
sha256.reset();
byte[] fullSHA = sha256.digest("3rfdfh6y-34rt-3rkl-9ijh-
mg94kgjdhsg3".toLowerCase().getBytes());
//printhash(fullSHA);
byte[] aesIV = new byte[BLOCK_BYTES];
System.arraycopy(fullSHA, 0, aesIV, 0, BLOCK_BYTES);

// Set up the IV and two cipher objects, one to encrypt and
// one to decrypt:
IvParameterSpec aesParameterSpec = new IvParameterSpec(aesIV);
AlgorithmParameters aesParameters = AlgorithmParameters.getInstance
("AES");
aesParameters.init(aesParameterSpec);

// And this is where it bombs because it expects argument2
// to be a key or certificate
//SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey,
0,aesKey.length,"AES");
//Replaced with this one that uses a bytearray as a key
SecretKeySpec aesKeySpec = new SecretKeySpec(aesPaddedKey,
0,aesPaddedKey.length,"AES");
//aesCrypt.init(Cipher.ENCRYPT_MODE, aesKey, aesParameters);
//aesDecrypt.init(Cipher.DECRYPT_MODE, aesKey, aesParameters);


m_objCrypt.init(Cipher.ENCRYPT_MODE, aesKeySpec, aesParameters);
m_objDecrypt.init(Cipher.DECRYPT_MODE, aesKeySpec, aesParameters);


public String EncryptValue(String Value) {

String returnValue = null;
if (Value.length() >= MAX_QUERY_LENGTH)
{
try {
throw new Exception();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

byte[] byaRawText = null;
try {
byaRawText = Value.getBytes("US-ASCII");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] byaCipherText = null;
try {
byaCipherText = m_objCrypt.doFinal(byaRawText, 0,
byaRawText.length);
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


returnValue = b64encode(byaCipherText);
System.out.println("base 64d ok");



return returnValue;

}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Thanks in advance. I know this is a lot to ask someone to look at.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Programming Cryptography in J2SE 1.3.1 Zheng Da Java 2 04-29-2006 02:47 PM
Re: "System.Security.Cryptography.CryptographicException: Bad Data" Message Dei401 ASP .Net 0 02-02-2005 04:30 PM
Generating hashes (System.security.cryptography) Mauricio Correa L. ASP .Net 1 06-18-2004 01:45 PM
cryptography library a_the_s@hotpop.com C++ 1 11-02-2003 10:42 PM
cryptography software Apple Java 1 10-12-2003 09:39 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57