|
Nikolai,
When I was testing my function and I specified your string, I got error message
"Specified key is a known weak key for TripleDES and cannot be used"
Does this mean, its too easy for users to guess your key and we need to change it?
Manmohan
|
|
|
|
|
Hi, the problem is principle, the buffer length calculation is wrong, because the encrypted byte array can contain '0' character. I tested it with DESCryptoServiceProvider.
Now I testing the class with TripleDESCryptoServiceProvider, it seams to have some problems with the key length calculation (method GetLegalKey)... When I found the problem I will let you know.
|
|
|
|
|
Hi everyone,
I think I found problem with Initialization Vector (IV), the IV size should be one block length, but the GetLegalKey method calculates the encryption key size, which, in case using TripleDESCryptoServiceProvider, is 128 bits, but the block size of TripleDES algorithm is 64 bits. In this case the System.Security.Cryptography.CryptographicException thrown...
I think we should use some other algorithm for IV generation or use overriden version of SymmetricAlgorithm.GenerateIV method. One of possibilities is to use part of the encryption key with one block length...
Nikolai
|
|
|
|
|
Hi again,
in the Internet I found following explanation of your problem:
Q) I keep getting the message "Specified key is a known weak key for TripleDES and cannot be used". What does this mean?
A) This means that the phrase or key that you entered would be very easy to for someone to guess or "hack" if they were to ever login to your account. Please use a different key.
URL: http://www.finalpartings.com/faq.aspx#q17
I hope this will help you...
Nikolai
|
|
|
|
|
Is anyone familiar with "Polar Crypto Light"? I was trying to Decrypt some data encrypted by that Component but was unsuccessful even though I know the "Password" to un-encrypt the data. Apparently it uses the "Rijndael / AES" algorithm with a 256-bit Key, CBC Mode, and a NULL "Initialization Vector".
Does anyone know of an implementation of Decrypting data from Polar Crypto Light? It seems like it should be able to be done, however, I've tried 5 examples of Source Code and none of them will Decrypt it. Any help is appreciated!
|
|
|
|
|
What's the preferred crypto to use in these instances? Anyone have an oppinion of what's best?
|
|
|
|
|
I added the suggested code fixes (VB.Net version). DES and Rijndael work fine, but RC2 gets the following error:
'' read out the result from the Crypto Stream
Dim sr As System.IO.StreamReader = New ystem.IO.StreamReader(cs)
Return sr.ReadToEnd() ***This line has the error***
End Function
[CryptographicException: Bad Data.]
System.Security.Cryptography.CryptoAPITransform._DecryptData(IntPtr hKey,
Byte[] rgb, Int32 ib, Int32 cb, Boolean fDone) +0
System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(
Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +1007
System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset,
Int32 count) +802
System.IO.StreamReader.ReadBuffer(Char[] userBuffer, Int32 userOffset,
Int32 desiredChars, Boolean& readToUserBuffer) +68
System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count) +125
System.IO.StreamReader.ReadToEnd() +93
SecurIt.Crypto.SymmCrypto.Decrypting(String Source, String Key) in
C:\ATEC System.root\ATEC System\SecurityLayer\UserSecurity.vb:141
Here's what I used to test it (ASP.Net):
Private Sub btnRunTest_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnRunTest.Click
Dim objCrypto As SymmCrypto = New SymmCrypto
Dim countBad As Integer = 0
Dim countGood As Integer = 0
Dim sPswd As String 'ASCII char
Dim pswdLength As Integer
Dim tmpString1, tmpString2 As String
Dim i, j As Integer
Dim rand As New Random(CInt(Date.Now.Ticks And Integer.MaxValue))
txtRunTest.Text = ""
For i = 1 To txtHowMany.Text
sPswd = ""
'get password length between 1 and 30
pswdLength = rand.Next(1, 30)
'build password string by selecting random Ascii
'characters between "0" and "z"
For j = 1 To pswdLength
sPswd &= Chr(rand.Next(48, 122))
Next
'Get a random key between 1 and 1M
Key = rand.Next(1, 1000000).ToString
objCrypto.SymmCrypto(SymmCrypto.SymmProvEnum.RC2)
tmpString1 = objCrypto.Encrypting(sPswd, Key)
tmpString2 = objCrypto.Decrypting(tmpString1, Key)
If tmpString2.Equals(sPswd) Then
countGood += 1
Else
countBad += 1
End If
Next
txtRunTest.Text = "Test Complete. Good=" & countGood.ToString & _
" Bad=" & countBad.ToString
End Sub
Note: If I set the key to "12345" it still fails.
It passes for 100,000 items using DES or Rijndael.
Thanks, Gord.
|
|
|
|
|
Hey,
i always get an error by decrypting the data with Rijndael algorythm. Not only with your samples but generally. It means that the to decrypt is has the wrong lenth. Here i have Windows 2000 Professional. I dont understand it. Is there anyone out that knows what can be the problem here!?
|
|
|
|
|
You have to set your key to the correct length. Rijndael requires a key of 16.
|
|
|
|
|
during DES encrption...whether we enter the correct value for key....Yet error come..bcoz during encrption...lenth of encrpted data is less ..and hence decrption of the same cause errror..
put string to encrpt:"Kunal"
this cause errroe though we have correct lenth of key..
try
|
|
|
|
|
First, thank you for the code and everyone for the helpful feedback. I do have a question, this works for me if I use DES, Rijndael, and RC2. I get invalid cast or an IV key length exception when I try any of the others. Any ideas how to get all of the other encryption classes to work, dynamically?
Thanks,
Mike
|
|
|
|
|
Thank u Frank!
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace FangHome_Crypto
{
public class SymmCrypto
{
public enum SymmProvEnum : int
{
DES, RC2, Rijndael, TripleDES
}
private SymmetricAlgorithm mobjCryptoService;
public SymmCrypto(SymmProvEnum NetSelected)
{
switch (NetSelected)
{
case SymmProvEnum.DES:
mobjCryptoService = new DESCryptoServiceProvider();
break;
case SymmProvEnum.RC2:
mobjCryptoService = new RC2CryptoServiceProvider();
break;
case SymmProvEnum.Rijndael:
mobjCryptoService = new RijndaelManaged();
break;
case SymmProvEnum.TripleDES:
mobjCryptoService = new TripleDESCryptoServiceProvider();
break;
}
}
public SymmCrypto(SymmetricAlgorithm ServiceProvider)
{
mobjCryptoService = ServiceProvider;
}
private byte[] GetLegalKey(string Key)
{
string sTemp = Key;
mobjCryptoService.GenerateKey();
byte[] bytTemp = mobjCryptoService.Key;
int KeyLength = bytTemp.Length;
if (sTemp.Length > KeyLength)
sTemp = sTemp.Substring(0, KeyLength);
else if (sTemp.Length < KeyLength)
sTemp = sTemp.PadRight(KeyLength, ' ');
return ASCIIEncoding.ASCII.GetBytes(sTemp);
}
private byte[] GetLegalIV()
{
string sTemp = "救臆妲饣";
mobjCryptoService.GenerateIV();
byte[] bytTemp = mobjCryptoService.IV;
int IVLength = bytTemp.Length;
if (sTemp.Length > IVLength)
sTemp = sTemp.Substring(0, IVLength);
else if (sTemp.Length < IVLength)
sTemp = sTemp.PadRight(IVLength, ' ');
return ASCIIEncoding.ASCII.GetBytes(sTemp);
}
public string Encrypting(string Source, string Key)
{
byte[] bytIn = UTF8Encoding.UTF8.GetBytes(Source);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
mobjCryptoService.Key = GetLegalKey(Key);
mobjCryptoService.IV = GetLegalIV();
ICryptoTransform encrypto = mobjCryptoService.CreateEncryptor();
CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
ms.Close();
byte[] bytOut = ms.ToArray();
return System.Convert.ToBase64String(bytOut);
}
public string Decrypting(string Source, string Key)
{
byte[] bytIn = System.Convert.FromBase64String(Source);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);
mobjCryptoService.Key = GetLegalKey(Key);
mobjCryptoService.IV = GetLegalIV();
ICryptoTransform encrypto = mobjCryptoService.CreateDecryptor();
CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
System.IO.StreamReader sr = new System.IO.StreamReader( cs );
return sr.ReadToEnd();
}
}
}
The first thing in life is running !
|
|
|
|
|
still doesn't work same error.
so no thanks Frank.
|
|
|
|
|
|
|
From the Logic Layer , What should you pass as the Source string and as the Key?
Happy Programming!
Regards,
ctrlnick !
|
|
|
|
|
OK, so heres the thing.
I discovered some instances where what I put in doesn't equal what I get back. To test this I did the following code against a version of the above code (perhaps an older version).
Just for clarity the code that tests this is below.
Anyway if 0.5% of cases the decrypted result does *not* equal what I put in. So watch out !
public static int Run()
{
CreditSights.Helper.Encryptor oEncryptor = new FangHome_Crypto.SymmCrypto(FangHome_Crypto.SymmCrypto.SymmProvEnum.Rijndael);
int countGood =0;
int countBad =0;
for (int i=0; i<1000000;i++)
{
//"ij1g5j"; example of bad pass for this key
// the following line calls GeneratePassword() which randomly
// generates a password consisting of 6 letters or numbers
string decryptedPassword1 = GeneratePassword();
string encryptedPassword = oEncryptor.Encrypting(decryptedPassword1, Key);
string decryptedPassword2 = oEncryptor.Decrypting(encryptedPassword, Key);
if (!decryptedPassword2.Equals(decryptedPassword1))
{
countBad++;
}
else
{
countGood++;
}
}
// outputs numbers like "0.00601870536419309" or "0.00521232321222"
System.Console.WriteLine("countBad/total = " + ((double) countBad)/((double)(countGood+countBad)));
}
|
|
|
|
|
Hello all,
Thought ya'll might want to know what I did to fix the problem I described above.
This is all very much thank you to the comments of Indra Gunawan in particular.
Note that, even though Frank has updated his code, I still had to update even that code with the suggestions of Indra G, in order to get my tests to work.
With the following changes, in my particular case, I get no errors.
Thanks again to Frank who posted the code in the first place.
//------
// in GetLegalKey()..
//------------
// safer to use default encoding so changed this..
//return ASCIIEncoding.ASCII.GetBytes(sTemp);
// to this..
return System.Text.Encoding.Default.GetBytes(sTemp);
//------------
// in Encrypting()..
//------------
// changed this..
// byte[] bytOut = ms.GetBuffer();
// int i = 0;
// for (i = 0; i < bytOut.Length; i++)
// if (bytOut[i] == 0)
// break;
//
// // convert into Base64 so that the
// // result can be used in xml
// return System.Convert.ToBase64String(bytOut, 0, i);
// to this..
byte[] bytOut = ms.ToArray();
return System.Convert.ToBase64String(bytOut);
//------------
|
|
|
|
|
Even with your fixes, it will still fail because you are using System.Text.Encoding.Default.GetBytes(sTemp); On most US/European system, it will most likely work. But it will not work in Japanese/Chinese systems, because the Default would be Shift-JIS/Big5/GB2312, the byte-array will definitely contains invalid data. To resolve this problem, a proper hack is to use System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(sTemp);
|
|
|
|
|
// Here's a version that I got working VERY fast and that
// supports all 4 synch crypt types. I've enhanced several
// of the basic operations to include some basic checks,
// standardization of the calls instead of byte-by-byte
// operations, and a few enhanced functions such as
// DecryptToHash and DecrtypeToHashBase64.
// Enjoy !
//
// 12-10-2002
// Corrected code resubmitted.
// Enhanced support for IV
// Made Rijndael (AES) the default
//
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace FangHome_Crypto
{
/// <summary>
/// SymmCrypto is a wrapper of System.Security.Cryptography.SymmetricAlgorithm classes
/// and simplifies the interface. It supports customized SymmetricAlgorithm as well.
/// </summary>
public class SymmCrypto
{
/// <remarks>
/// Supported .Net intrinsic SymmetricAlgorithm classes.
/// </remarks>
public enum SymmProvEnum : int
{
Rijndael, RC2, TripleDES, DES
}
private SymmetricAlgorithm mobjCryptoService;
public String Key;
public String Vector;
/// <remarks>
/// Default Constructor (uses Rijndael by default)
/// </remarks>
public SymmCrypto()
{
mobjCryptoService = new RijndaelManaged();
}
public SymmCrypto(string TheKey, string TheVector)
{
mobjCryptoService = new RijndaelManaged();
Key = TheKey;
Vector = TheVector;
}
/// <remarks>
/// Constructor for using an intrinsic .Net SymmetricAlgorithm class.
/// </remarks>
public SymmCrypto(SymmProvEnum NetSelected)
{
switch (NetSelected)
{
case SymmProvEnum.DES:
mobjCryptoService = new DESCryptoServiceProvider();
break;
case SymmProvEnum.RC2:
mobjCryptoService = new RC2CryptoServiceProvider();
break;
case SymmProvEnum.Rijndael:
mobjCryptoService = new RijndaelManaged();
break;
case SymmProvEnum.TripleDES:
mobjCryptoService = new TripleDESCryptoServiceProvider();
break;
}
}
public SymmCrypto(SymmProvEnum NetSelected, String TheKey, String TheVector)
{
switch (NetSelected)
{
case SymmProvEnum.DES:
mobjCryptoService = new DESCryptoServiceProvider();
break;
case SymmProvEnum.RC2:
mobjCryptoService = new RC2CryptoServiceProvider();
break;
case SymmProvEnum.Rijndael:
mobjCryptoService = new RijndaelManaged();
break;
case SymmProvEnum.TripleDES:
mobjCryptoService = new TripleDESCryptoServiceProvider();
break;
}
Key = TheKey;
Vector = TheVector;
}
/// <remarks>
/// Constructor for using a customized SymmetricAlgorithm class.
/// </remarks>
public SymmCrypto(SymmetricAlgorithm ServiceProvider)
{
mobjCryptoService = ServiceProvider;
}
/// <remarks>
/// Depending on the legal key size limitations of a specific CryptoService provider
/// and length of the private key provided, padding the secret key with space character
/// to meet the legal size of the algorithm.
/// </remarks>
private byte[] GetLegalKey(string Key)
{
if (mobjCryptoService.LegalKeySizes.Length > 0)
{
int lessSize = 0, moreSize = mobjCryptoService.LegalKeySizes[0].MinSize;
// key sizes are in bits
while (Key.Length * 8 > moreSize && mobjCryptoService.LegalKeySizes[0].SkipSize > 0 && moreSize < mobjCryptoService.LegalKeySizes[0].MaxSize)
{
lessSize = moreSize;
moreSize += mobjCryptoService.LegalKeySizes[0].SkipSize;
}
if(Key.Length > (moreSize / 8))
return ASCIIEncoding.ASCII.GetBytes(Key.Substring(0, (moreSize / 8)));
else
return ASCIIEncoding.ASCII.GetBytes(Key.PadRight(moreSize / 8, ' '));
}
else
return ASCIIEncoding.ASCII.GetBytes(Key);
}
private byte[] GetLegalIV(String Vector, int ivLength)
{
return ASCIIEncoding.ASCII.GetBytes(Vector.Substring(0, ivLength));
}
public string Encrypt(string Source)
{
if(Source==null || Key==null || Source.Length==0 || Key.Length == 0)
return "";
byte[] bytIn = System.Text.ASCIIEncoding.ASCII.GetBytes(Source);
// create a MemoryStream so that the process can be done without I/O files
System.IO.MemoryStream ms = new System.IO.MemoryStream();
// set the private key
mobjCryptoService.Key = GetLegalKey(Key);
mobjCryptoService.IV = GetLegalIV(Vector, mobjCryptoService.IV.Length);
// create Crypto Stream that transforms a stream using the encryption
CryptoStream cs = new CryptoStream(ms, mobjCryptoService.CreateEncryptor(), CryptoStreamMode.Write);
// write out encrypted content into MemoryStream
cs.Write(bytIn, 0, bytIn.Length);
cs.FlushFinalBlock();
// convert into Base64 so that the result can be used in xml
return System.Convert.ToBase64String(ms.GetBuffer(), 0, (int) ms.Length);
}
public string DecryptToHashBase64(string Source)
{
MD5CryptoServiceProvider H = new MD5CryptoServiceProvider();
return System.Convert.ToBase64String(
H.ComputeHash(
System.Text.ASCIIEncoding.ASCII.GetBytes(
Decrypt(Source))));
}
public string DecryptToHash(string Source)
{
MD5CryptoServiceProvider H = new MD5CryptoServiceProvider();
return System.Text.ASCIIEncoding.ASCII.GetString(
H.ComputeHash(
System.Text.ASCIIEncoding.ASCII.GetBytes(
Decrypt(Source))));
}
public string Hash(string Source)
{
MD5CryptoServiceProvider H = new MD5CryptoServiceProvider();
return System.Text.ASCIIEncoding.ASCII.GetString(
H.ComputeHash(
System.Text.ASCIIEncoding.ASCII.GetBytes(Source)));
}
public string HashBase64(string Source)
{
MD5CryptoServiceProvider H = new MD5CryptoServiceProvider();
return System.Convert.ToBase64String(
H.ComputeHash(
System.Text.ASCIIEncoding.ASCII.GetBytes(Source)));
}
public string Decrypt(string Source)
{
if(Source==null || Key==null || Source.Length==0 || Key.Length == 0)
return "";
// convert from Base64 to binary
byte[] bytIn = System.Convert.FromBase64String(Source);
// create a MemoryStream with the input
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);
// set the private key
mobjCryptoService.Key = GetLegalKey(Key);
mobjCryptoService.IV = GetLegalIV(Vector, mobjCryptoService.IV.Length);
// create Crypto Stream that transforms a stream using the decryption
CryptoStream cs = new CryptoStream(ms, mobjCryptoService.CreateDecryptor(), CryptoStreamMode.Read);
// read out the result from the Crypto Stream
System.IO.StreamReader sr = new System.IO.StreamReader( cs );
return sr.ReadToEnd();
}
}
}
Sincerely,
William M. Rawls
Brainbench MVP for Visual Basic
http://www.brainbench.com
4017 Block Dr #2159
Irving, TX 75038
wrawls@firmsolutions.com
Cell: 972-365-2981
Home: 972-607-2550
Work: 972-507-3756
MSN:willrawls@hotmail.com
Welcome to the Evolution
==================
http://www.sliceanddice.com
|
|
|
|
|
I should note that this version experiences no "bad data" or other errors. I've tested all 4 algorythms several thousand times without error.
Sincerely,
William M. Rawls
Brainbench MVP for Visual Basic
http://www.brainbench.com
4017 Block Dr #2159
Irving, TX 75038
wrawls@firmsolutions.com
Cell: 972-365-2981
Home: 972-607-2550
Work: 972-507-3756
MSN:willrawls@hotmail.com
Welcome to the Evolution
==================
http://www.sliceanddice.com
|
|
|
|
|
I got the following exception on your version, when decrypting a string:
---------------------------------------------
An unhandled exception of type 'System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll
Message: "PKCS7 padding is invalid and cannot be removed."
---------------------------------------------
The exception is thrown on the last line of the Decrypt method:
return sr.ReadToEnd();
Here's my code that's calling it:
string encryptionKey = "Xwhuuebll1jkh88er4jhsWWvlkejf";
SymmCrypto s = new SymmCrypto(SymmCrypto.SymmProvEnum.Rijndael);
string toReturn = s.Decrypt(encryptedString, encryptionKey);
s = null;
return toReturn;
|
|
|
|
|
Sorry, I guess I uploaded the wrong version. Please copy the newly updated version and try again.
Sincerely,
William M. Rawls
Brainbench MVP for Visual Basic
http://www.brainbench.com
2201 Wingren Rd
Irving, TX 75062-4680
wrawls@firmsolutions.com
Cell: 972-365-2981
Home: 972-607-2550
Work: 972-507-3520
Fax:561-325-5977
MSN:willrawls@hotmail.com
Welcome to the Evolution
==================
http://www.sliceanddice.com
|
|
|
|
|
If the Vector Length is less than IV.Length it generates an error.
This fixed the problem:
<br />
private byte[] GetLegalIV(string vector, int ivLength)<br />
{<br />
if (vector.Length > ivLength)<br />
return ASCIIEncoding.ASCII.GetBytes(vector.Substring(0, ivLength));<br />
else<br />
return ASCIIEncoding.ASCII.GetBytes(vector.PadRight(ivLength));<br />
}<br />
Regards,
Aquele Abraço,
Bruno Oliveira
Tecnologia Takenet
+55. 31. 3295.6308
+55. 31. 8803.6267 _gsm
|
|
|
|
|
KB Article is not available.
|
|
|
|
|