From: Scooter on
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.
From: rossum on
On Mon, 17 Nov 2008 11:58:47 -0800 (PST), Scooter
<slbentley(a)gmail.com> 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;

Cipher myCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
The Cipher parameters must obviously match the equivalent on the C#
side: Algorithm, mode and padding method.

myCipher.init(Cipher.DECRYPT_MODE,
decryptionKey,
otherParameters);
Other parameters covers things like the IV (for CBC mode) or the nonce
(for CTR mode) or whatever else is needed.


>
> if (EncryptedValue.length() >= 0x800) {
throw new PickYourException("Decoding:
buffer length exceeded.");
> }
>
> try
> {
> byte[]inputBuffer=new
> sun.misc.BASE64Decoder().decodeBuffer(EncryptedValue);
Do not use sun.misc for any production code, it cannot be relied on.
Find a decent Base64 converter on the web (there are hundreds) and
either copy or import that.

> //buffer=
buffer = myCipher.doFinal(inputBuffer);


> }
> catch (Exception e)
> {
Cipher.doFinal() may throw IllegalStateException,
IllegalBlockSizeException or BadPaddingException. Check the Javadoc
for details.


> }
>
>
>I just have no idea about converting that whole "TransformFinalBlock"
>method.
It seems to be the equivalent of the Cipher.doFinal() methods. See
the Javadoc for javax.crypto.Cipher at
http://java.sun.com/javase/6/docs/api/javax/crypto/Cipher.html

For a specific overview of Java cryptography have a look at the JCA
Guide, particularly the section on the Cipher class:
http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html

>
>Any suggestions are appreciated.

HTH

rossum

From: Arne Vajhøj on
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);
}
}
From: Arne Vajhøj on
rossum wrote:
> On Mon, 17 Nov 2008 11:58:47 -0800 (PST), Scooter
> <slbentley(a)gmail.com> wrote:
>> byte[]inputBuffer=new
>> sun.misc.BASE64Decoder().decodeBuffer(EncryptedValue);
> 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
From: Scooter on
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();