 |
|
 |
Hi,
thanks for your code!
I found a small bug in the IV property:
public byte[] IV { get { return IV; } }
This should be 'return iv;' so the property doesn't try to call it's own Get function..
Best Regards
Niko
|
|
|
|
 |
|
 |
Totally correct, thanks. As you may guess, I have never used that property :P
|
|
|
|
 |
|
 |
Is there any license attached to this code? Can I use this code in a proprietary project? It's exactly what I have been looking for.
|
|
|
|
 |
|
 |
I originally released it basically competely free for use. Since CP have started asking us to license our code I am using the CodeProject Open License. I believe that does allow you to use the code as you wish; that's certainly the intention. It would be nice if you linked from your About box or documentation though
|
|
|
|
 |
|
 |
Will do. Thanks for the code.
|
|
|
|
 |
|
 |
Hi there! This project has been of great help, and I've managed to successfully encript in Java and decript in .NET 1.1.
A little suggestion of improvement: to use the class for encripting and decripting, Generate could return void instead of the Encriptor, and request the Encriptor (or Decriptor) according to the operation to be done...
keep the good work!
|
|
|
|
 |
|
 |
Is there a way to adapt this code to work with TripleDES? I know i java there is also a "PBEWithMD5AndTripleDES". What hash algorithm would you use in this case? Also, what would be the number of segments and iterations passed into the Generate method?
|
|
|
|
 |
|
 |
Sorry, I don't know how that algorithm works. My guess is it does the same thing but generates 3 blocks of 8 bytes as the key. .Net provides a TripleDES encryptor, so you can probably modify the code to use that.
|
|
|
|
 |
|
 |
So I have to ecrypt something using PBEWithMD5AndDES encryption from .net to be decrypted in a java app.
In java, to encrypt it I go:
private byte[] _salt = {
(byte) 0xc7,
(byte) 0x73,
(byte) 0x21,
(byte) 0x8c,
(byte) 0x7e,
(byte) 0xc8,
(byte) 0xee,
(byte) 0x99 };
private int _count = 13;
private PBEParameterSpec _pbeParamSpec = new PBEParameterSpec(_salt, _count);
public static void main(String[] args)
{
Main enc = new Main();
SecretKey key = enc.setKeyString("abcdefghijklm");
byte[] arg;
encryptString("4123321123321")
}
public String encryptString(String num)
{
byte[] eccbytes = encrypt(setKeyString("abcdefghijklm"), num.getBytes());
StringBuffer encrypted_string_sb = new StringBuffer();
for (int i = 0; i < eccbytes.length; i++) {
char c = (char) (eccbytes[i] & 0Xff);
encrypted_string_sb.append(c);
}
return encrypted_string_sb.toString();
}
public byte[] encrypt(SecretKey key, byte[] clearText)
{
byte[] encryptedText = null;
try
{
// Create PBE Cipher
Cipher c = Cipher.getInstance("PBEWithMD5AndDES");
// Create PBE parameter set
//PBEParameterSpec pbeParamSpec = new PBEParameterSpec(_salt, _count);
// Initialize PBE Cipher with key and parameters
c.init(Cipher.ENCRYPT_MODE, key, _pbeParamSpec);
//encryptedText = new String(c.doFinal(clearText.getBytes()));
encryptedText = c.doFinal(clearText);
}
catch (Exception e)
{
System.out.print(e.toString());
}
return encryptedText;
}
Now, I can't seem to emulate this in .net. I've implemented the class posted here and used the "TransformFinalBlock" method but I've been unable to get the proper results. Would someone mind posting an example of this being implemented.
Thanks in advance,
Matt
|
|
|
|
 |
|
 |
This is exactly the scenario I wrote the code for, encyrpting data for consumption by Java. Here is an example:
PKCSKeyGenerator crypto = new PKCSKeyGenerator(
"mysecretkey",
new byte[]{ 37, 189, 4, 14, 27, 109, 215, 47 }, 13, 1 );
ICryptoTransform ct = crypto.Encryptor;
String command = "whatever you want to encrypt";
byte[] newbytes = ct.TransformFinalBlock(Encoding.UTF8.GetBytes(command), 0, command.Length);
|
|
|
|
 |
|
 |
***EDIT*** Thanks again for your help.
I got it working. It had to do with my buffer between the two apps. Great article.
Thank you for the quick response, I really appreciate it. That's pretty much what I did, but the bytes don't seem to be the same. I actually just noticed that there are no negative bytes in .net. So I may have just been misinterpreting it.
so for
PKCSKeyGenerator crypto = new PKCSKeyGenerator(
"abcdefghijklm",
new byte[] { 37, 189, 4, 14, 27, 109, 215, 47 }, // salt
13, 1);
ICryptoTransform ct = crypto.Encryptor;
String command = "abcdefghijkmnopq";
byte[] newbytes = ct.TransformFinalBlock(Encoding.UTF8.GetBytes(command), 0, command.Length);
In .net my byte array results for :
166
236
55
116
222
233
31
37
31
144
191
38
102
179
29
219
51
69
89
12
54
138
95
150
whereas in Java they are:
-50
-12
-104
-7
-114
74
-67
125
-92
63
17
5
57
-82
-85
-31
80
58
-97
65
31
-29
41
104
-- modified at 16:05 Wednesday 7th February, 2007
|
|
|
|
 |
|
 |
I am trying to use below mentioned code in .net.
PKCSKeyProvider kp = new PKCSKeyProvider();
ICryptoTransform crypt = kp.Generate(
"MyPassword",
new byte[] { 100, 200, 255, 3}, // salt
15, // iterations of MD5 hashing
1 ); // number of 16-byte segments to create.
// 1 to mimic Java behaviour.
.net is not recognizing "PKCSKeyProvider" .
I am using .net 2.0.
Please guide me how to use it.
Regards,
|
|
|
|
 |
|
 |
PKCSKeyGenerator, my mistake
|
|
|
|
 |
|
 |
In your efforts to migrate from Java to .NET, did you also happen to have to decrypt in .NET something that was encrypted in Java using PBEwithMD5andDES? It seems like you could add the following property to your class and have it work, but I'm not entirely sure:
public ICryptoTransform Decryptor { get { return des.CreateDecryptor(key, iv); } }
The reason I'm not entirely sure is because I don't know Java encryption well, so if there is some reason using a decryptor in your code won't work, could you explain why?
Thank you for the excellent article.
audiedog
|
|
|
|
 |
|
 |
No, I didn't have to decrypt anything (my translation project was the part of the application that encrypted the data, the decryption is still done in Java so far). However, the 'PBEwithMD5' part is just generating a DES key, so yes, that should work fine.
|
|
|
|
 |
|
 |
Great. I'm in the process of testing it now, and I'll let you know how it turns out. The other thing I did was remove the constructor that had no parameters so the key and IV had to be generated on instantiation. Thanks again for the article; it helped me a lot.
audiedog
|
|
|
|
 |
|
 |
Hi,
did you get this working?
I tried your method of adding the Decryptor line, but my C# code keeps coming back with the error:
Exception occurred= System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
at System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Test.Decrypt(String obj, String key) in
...
An unhandled exception of type 'System.InvalidOperationException' occurred in system.dll
I get this error when the java webservice returns the encrypted string.
In C#, I was able to encrypt and decrypt strings using the class. I was even successful passing an encrypted string from C# to Java and have it decrypt successfully in the webservice. However, when I encrypt a string in the webservice and pass it back to C#, the error comes up.
Any ideas?
|
|
|
|
 |
|
 |
Nevermind, I got it working. The java source I was using was using the sun.misc.Base64 class and I changed it to use base64 class from iharder.net... however, my encrypt function was using the wrong encode method (ie. encodeObject instead of encodeBytes).
Thanks for the great resource! I don't know where I'd be without codeproject.
|
|
|
|
 |
|
 |
I made this code for decrypting. I hope that helps
/*Decrypt*/
ICryptoTransform de = kp.Decryptor;//Create Decrypter
byte[] pnlContent = System.Convert.FromBase64String(str); //Convert to bytes
byte[] DataHolderD = de.TransformFinalBlock(pnlContent, 0, pnlContent.Length); //Decrypt to bytes
str = Encoding.UTF8.GetString(DataHolderD); //Convert to String
|
|
|
|
 |
|
 |
I am trying to use your sample code but it didnot help. can you make a simple example which takes string and encrypt it and decrypt it?
thanks in advance
|
|
|
|
 |
|
 |
Amazing work! The decryption works perfectly.
|
|
|
|
 |
|
 |
Hello!
Nice article but only one comment. THis is pretty nice concept but still it's missing good crypto background because of MD5. Then it can be attacked by current type of MD5 attacks. Our cryptoanalysts as Vlastimil Klima presented on Prague's faculty.
More here: http://cryptography.hyperlink.cz/MD5_collisions.html
So this is the issue for this algorith to rely with any crypto operation on MD5.
Regads,
Jan Seda
www.skilldrive.com
|
|
|
|
 |
|
 |
Jan - the point of this article isn't to put this forward as a good encryption algorithm, it's to provide compatibility with data encrypted using this algorithm from Java.
Any run of the algorithm with the same arguments produces the same key and IV, so imho it would make more sense just to store the key and the IV instead of the password and salt. However Java lets you do it this way and it's easier to migrate with this class .
Naturally, any security method in which the key is stored in the application is somewhat vulnerable!
|
|
|
|
 |
|
 |
Yes, this is true and I just wanted to point out the MD5 issue Anyway this topic regarding storing key inside of your application is very important a i wrote some thesis about it, there are some mathematical ways how to to do it (like some of them are used in DRM) but this is not a matter of this article
As I said, I just wanted to point out that MD5 is dead
Regards,
Jan Seda
www.skilldrive.com
|
|
|
|
 |