07-09-2010 10:22 AM
If you are seeing a different result each time, then the problem is most likely in your code.
I suggest you post your code and we can see what is wrong with it?
Actually I'll change my mind, instead of showing us your real code, create a small snippet that shows the problem. This will be a good test to, because if your small snippet does not show this changing result, then you will know where to look for the problem in your own code.
07-09-2010 05:52 PM
Hi
I have aadded the following code:
package com.rim.samples.device.cryptodemo;
import java.io.*;
import net.rim.device.api.crypto.*;
import net.rim.device.api.util.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
class CryptoDemo extends UiApplication
{
private RichTextField _status;
public static void main( String[] args )
{
CryptoDemo theApp = new CryptoDemo();
theApp.enterEventDispatcher();
}
private CryptoDemo()
{
MainScreen screen = new MainScreen();
screen.setTitle(new LabelField("Crypto Demo", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));
_status = new RichTextField("Select 'Go' from the menu to perform the test.");
screen.add(_status);
screen.addMenuItem(new MenuItem("Go" , 100, 10)
{
public void run()
{
go();
}
});
pushScreen(screen);
}
private void go()
{
try
{
String message = "jorge";
byte[] ba = "70789198PABLOHERBASCAMPOS".getBytes();
TripleDESKey key = new TripleDESKey(ba);
TripleDESEncryptorEngine encryptionEngine = new TripleDESEncryptorEngine( key );
PKCS5FormatterEngine formatterEngine = new PKCS5FormatterEngine( encryptionEngine );
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BlockEncryptor encryptor = new BlockEncryptor( formatterEngine, outputStream );
encryptor.write( message.getBytes() );
encryptor.close();
byte[] encryptedData = outputStream.toByteArray();
TripleDESDecryptorEngine decryptorEngine = new TripleDESDecryptorEngine( key );
PKCS5UnformatterEngine unformatterEngine = new PKCS5UnformatterEngine( decryptorEngine );
ByteArrayInputStream inputStream = new ByteArrayInputStream( encryptedData );
BlockDecryptor decryptor = new BlockDecryptor( unformatterEngine, inputStream );
byte[] temp = new byte[10];
DataBuffer db = new DataBuffer();
for( ;; )
{
int bytesRead = decryptor.read( temp );
if( bytesRead <= 0 )
{
// We have run out of information to read, bail out of loop.
break;
}
db.write(temp, 0, bytesRead);
}
byte[] decryptedData = db.toArray();
if( Arrays.equals( message.getBytes(), decryptedData ) )
{
_status.setText("Test Passed. The message is identical. \n\n Text: " + message + "\n\n Text Encrypt: " + message.getBytes());
}
else
{
_status.setText("Test Failed. The messages are different. ");
}
}
catch( CryptoTokenException e )
{
System.out.println(e.toString());
}
catch (CryptoUnsupportedOperationException e)
{
System.out.println(e.toString());
}
catch( IOException e )
{
System.out.println(e.toString());
}
}
}
I have define the value of MESSAGE static:
// Here is the data that we are going to encrypt.
String message = "jorge";
byte[] ba = "70789198PABLOHERBASCAMPOS".getBytes();
// Create a new random TripleDESKey.
TripleDESKey key = new TripleDESKey(ba);
// Create the encryption engine for encrypting the data.
TripleDESEncryptorEngine encryptionEngine = new TripleDESEncryptorEngine( key );
In the next time i have ran the application, the result is random every time i open the application.
Now, with the same KEY and messages used on blackberry application:
String message = "jorge";
byte[] ba = "70789198PABLOHERBASCAMPOS".getBytes();
I have implement on C# ASP.NET the decrypt process. The result every time that run the web app is the same.
When i send the value encrypted to web app, the first time is a value, the second time is other value
not the same, the third time is a difrent value. The Web app can not decrypt the same value.
IE Sample
In blackberry app:
the value to encrypt: "jorge"
KEY: ba = "70789198PABLOHERBASCAMPOS".getBytes();
result: xxxxxxxx
in Web app receive value xxxxxx
KEY ba = "70789198PABLOHERBASCAMPOS".getBytes();
result decrypt: yyyyyyyy not jorge
Any ideas, any sugestions, do you understand my problem?
Jorge
07-09-2010 07:48 PM
There are three issues here:
a) Why do you think the results are different each time you run this?
I suspect that is because you are thinking that your display on the screen is the encrypted data. It is not. If you attempt to display a byte array in the String like this:
message.getBytes()
you actually display a reference to the byte array not the contents of the byte array. If you want the contents of the byte array, put a break point in at this line and have a look at the contents. Or dump it out in hex using some code like what I have pasted below.
b) How do you get this data down to the Server for this test.
Remember that this is binary data - the encrypted data is not displayable. You can't convert this to a String and send it down. You can send the binary bytes, or you can convert the binary bytes into a text string (Base 64 encoding being the most frequently used method), transport the String, then have your Server do the reverse to recover the binary data. You need to make absolutely and 1005 sure that the bytes that the Server code attempts to decrypt are the bytes that your BlackBerry encryption has created.
c) Are you using exactly the same decryption?
As I think I have already noted on this Thread, it is very easy to slip on something and get the processing at each end slightly different. So triple check this. And make sure that your Server code will encrypt the same String to the same value as the Blackberry code. In fact have your Server encrypt something and then test that this is decrypted properly on the Blackberry. But remember this in binary data.....
Some code to dump out a byte array in a readable form. I'm sure this could be improved.
private static String HEXCHARS[] = {
"0", "1", "2", "3",
"4", "5", "6", "7",
"8", "9", "A", "B",
"C", "D", "E", "F"
};
/**
* Convert from byte array to String with Hex representation
* @param in - byte array to reformat
* @return - String representation
*/
public static String byteArrayToHexString(byte in[]) {
byte ch = 0x00;
int i = 0;
if (in == null || in.length <= 0) {
return null;
}
StringBuffer out = new StringBuffer(in.length * 2);
while (i < in.length) {
ch = (byte) (in[i] & 0xF0); // Strip off high nibble
ch = (byte) (ch >>> 4);
// shift the bits down
ch = (byte) (ch & 0x0F);
// must do this is high order bit is on!
out.append(HEXCHARS[ (int) ch]); // convert the nibble to a String Character
ch = (byte) (in[i] & 0x0F); // Strip off low nibble
out.append(HEXCHARS[ (int) ch]); // convert the nibble to a String Character
i++;
}
String rslt = out.toString();
return rslt;
}
07-10-2010 02:53 AM
I didnt understand any thing . Please explain me in brife :-(
07-10-2010 05:22 AM
I don't know what you don't understand?
07-12-2010 01:31 AM
Can you please explian with the small example in bb eclipse plugin with dotnet
07-13-2010 02:38 PM
I had a similar problem and came across this post. Incase someone else comes along this post here's my solution.
Like Peter mentioned above - the digest's binary data is not readable. So convert it to a hex representation and pass that string across to the server.
This is how I got it to work for me:
MD5Digest digest = new MD5Digest();
digest.update(password.getBytes(), 0, password.length());
String MD5password = byteArrayToHexString(digest.getDigest());
The byteArrayToHexString function is the one that Peter posted above. I'll repost it again below.
private static String HEXCHARS[] = {
"0", "1", "2", "3",
"4", "5", "6", "7",
"8", "9", "A", "B",
"C", "D", "E", "F"
};
/**
* Convert from byte array to String with Hex representation
* @param in - byte array to reformat
* @return - String representation
*/
public static String byteArrayToHexString(byte in[]) {
byte ch = 0x00;
int i = 0;
if (in == null || in.length <= 0) {
return null;
}
StringBuffer out = new StringBuffer(in.length * 2);
while (i < in.length) {
ch = (byte) (in[i] & 0xF0); // Strip off high nibble
ch = (byte) (ch >>> 4);
// shift the bits down
ch = (byte) (ch & 0x0F);
// must do this is high order bit is on!
out.append(HEXCHARS[ (int) ch]); // convert the nibble to a String Character
ch = (byte) (in[i] & 0x0F); // Strip off low nibble
out.append(HEXCHARS[ (int) ch]); // convert the nibble to a String Character
i++;
}
String rslt = out.toString();
return rslt;
}
Hope this helps!
07-13-2010 06:02 PM
for what it worth I prefer the bouncy castle way, it's surely more secure,
it's surely more portable and it works with every BB OS version.
07-13-2010 06:51 PM
I think the issue here is that the original poster does not know how to use encryption. Further confusing him/her with the need to install an external jar might not be advisable. Or is there a bouncy castle implementation in .Net that means the same code can be used on both BB and Server?
07-13-2010 08:05 PM
yes peter.