我现在手头在做一个项目的统一认证登录接口接口数据的加密方式是base64(3des(code));对称算法模式是CBC填充模式PKCS7对方是用JAVA的,我这边是用C#进行开发的。 我这边使用的3DES方法如下
#region 3DES加解密
/// <summary>
/// 3DES解密
/// </summary>
/// <param name="a_strString"></param>
/// <param name="a_strKey"></param>
/// <returns></returns>
public string Decrypt3DES(string a_strString, string a_strKey)
{
TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
provider.KeySize = 192;
provider.Key = KeyBytes();
provider.IV = Encoding.UTF8.GetBytes("12345678");
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = provider.CreateDecryptor();
string str = "";
try
{
byte[] inputBuffer = Convert.FromBase64String(a_strString);
str = Encoding.UTF8.GetString(transform.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length));
}
catch (Exception e)
{
MessageHelper.Alert(e.Message);
}
return str;
} /// <summary>
/// 3DES加密
/// </summary>
/// <param name="a_strString"></param>
/// <param name="a_strKey"></param>
/// <returns></returns>
public string Encrypt3DES(string a_strString, string a_strKey)
{
TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
provider.KeySize = 192;
provider.Key = KeyBytes();
provider.IV = Encoding.UTF8.GetBytes("12345678");
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = provider.CreateEncryptor();
byte[] bytes = Encoding.UTF8.GetBytes(a_strString);
return Convert.ToBase64String(transform.TransformFinalBlock(bytes, 0, bytes.Length));
}
#endregion密钥是对方给的48个字符(16进制的)所以上述代码中我将之转换成了字节数组。可是加密出来的和对方的一直对不上 我这边base64(3des("a"))的结果="qq84WJTIZcc="而对方的base64(3des("a"))的结果却="uZqJ8b6Lu90="请问是我的代码有问题吗?
#region 3DES加解密
/// <summary>
/// 3DES解密
/// </summary>
/// <param name="a_strString"></param>
/// <param name="a_strKey"></param>
/// <returns></returns>
public string Decrypt3DES(string a_strString, string a_strKey)
{
TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
provider.KeySize = 192;
provider.Key = KeyBytes();
provider.IV = Encoding.UTF8.GetBytes("12345678");
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = provider.CreateDecryptor();
string str = "";
try
{
byte[] inputBuffer = Convert.FromBase64String(a_strString);
str = Encoding.UTF8.GetString(transform.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length));
}
catch (Exception e)
{
MessageHelper.Alert(e.Message);
}
return str;
} /// <summary>
/// 3DES加密
/// </summary>
/// <param name="a_strString"></param>
/// <param name="a_strKey"></param>
/// <returns></returns>
public string Encrypt3DES(string a_strString, string a_strKey)
{
TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
provider.KeySize = 192;
provider.Key = KeyBytes();
provider.IV = Encoding.UTF8.GetBytes("12345678");
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = provider.CreateEncryptor();
byte[] bytes = Encoding.UTF8.GetBytes(a_strString);
return Convert.ToBase64String(transform.TransformFinalBlock(bytes, 0, bytes.Length));
}
#endregion密钥是对方给的48个字符(16进制的)所以上述代码中我将之转换成了字节数组。可是加密出来的和对方的一直对不上 我这边base64(3des("a"))的结果="qq84WJTIZcc="而对方的base64(3des("a"))的结果却="uZqJ8b6Lu90="请问是我的代码有问题吗?
解决方案 »
- .NET中有没有关于计算字符串相似度的现成的函数?
- 网站多人同时访问时错误 DataBinding:“System.Data.DataRowView”不包含名为“Contents”的属性。
- IEXPLORE.EXE发生未处理的WIN32异常
- FTP 上传文件报错
- window.close()
- 如何使ListVIew控件显示的项目背景色交错?
- 在删除GAC目录中的程序集时报"Assembly'...'could not be uninstalled because it is required by other applications."
- 关于接口简单问题。
- 怎样用WindowsMediaPlayer控件播放音频文件的任何一部分?
- 选择tabPage,dataGrid中的连接内容随之改变,怎么实现?
- DataGridView
- 关于savefiledialog控件的问题
不知道你KeyBytes()怎么实现的,貌似你的密钥a_strKey也没用到。下面给你一段代码,我之前做加密用的。
/// <summary>
/// 把字符串转换为字节数组
/// </summary>
/// <param name="strKey">源串</param>
public static byte[] covertStringToHex(string strKey)
{
int strLen = strKey.Length;
//字节长度是字符串的一半
int byLen = strKey.Length >> 1; byte[] key = new byte[byLen];
for (int i = 0, j = 0; i < byLen && j < strLen; i++)
{
key[i] = (byte)(convertCharToHex(strKey[j++]) << 4);
key[i] += (byte)(convertCharToHex(strKey[j++]) & 0xF);
}
return key;
} /// <summary>
///
/// </summary>
/// <param name="ch"></param>
/// <returns></returns>
public static int convertCharToHex(char ch)
{
if ((ch >= '0') && (ch <= '9'))
return ch - 0x30;
else if ((ch >= 'A') && (ch <= 'F'))
return ch - 'A' + 10;
else if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
else
return -1;
}
/// KEY
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
public static byte[] GetKeyBytes(string hex)
{
byte[] bytes = new byte[hex.Length / 2]; for (int i = 0; i < bytes.Length; i++)
{
try
{
// 每两个字符是一个 byte。 bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
System.Globalization.NumberStyles.HexNumber);
}
catch
{
// Rethrow an exception with custom message.
throw new ArgumentException("hex is not a valid hex number!", "hex");
}
}
return bytes;
}
3DES算法中,C#创建加密的时候可以指定模式的代码中有体现 provider.Mode = CipherMode.CBC;因为3DES算法可以指定某种对称算法模式在CBC模式中则一定要指定一个初始向量IV如果是EBC的话似乎可以不用指定的
我是第一次接触C#的3DES算法,以上说法如果有错误的话请指正
还请各位高手多多指教
其实总的来说都差不多,只是传进去的值是BYTE[]而已结果出来的base64(3des("a"))的结果还是="qq84WJTIZcc="附3DES代码
#region CBC模式**
/// <summary>
/// DES3 CBC模式加密
/// </summary>
/// <param name="key">密钥</param>
/// <param name="iv">IV</param>
/// <param name="data">明文的byte数组</param>
/// <returns>密文的byte数组</returns>
public static byte[] Des3EncodeCBC(byte[] key, byte[] iv, byte[] data)
{
//复制于MSDN
try
{
// Create a MemoryStream.
MemoryStream mStream = new MemoryStream();
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC; //默认值
tdsp.Padding = PaddingMode.PKCS7; //默认值
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(mStream,
tdsp.CreateEncryptor(key, iv),
CryptoStreamMode.Write);
// Write the byte array to the crypto stream and flush it.
cStream.Write(data, 0, data.Length);
cStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = mStream.ToArray();
// Close the streams.
cStream.Close();
mStream.Close();
// Return the encrypted buffer.
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
/// <summary>
/// DES3 CBC模式解密
/// </summary>
/// <param name="key">密钥</param>
/// <param name="iv">IV</param>
/// <param name="data">密文的byte数组</param>
/// <returns>明文的byte数组</returns>
public static byte[] Des3DecodeCBC(byte[] key, byte[] iv, byte[] data)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream(data);
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC;
tdsp.Padding = PaddingMode.PKCS7;
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
tdsp.CreateDecryptor(key, iv),
CryptoStreamMode.Read);
// Create buffer to hold the decrypted data.
byte[] fromEncrypt = new byte[data.Length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Convert the buffer into a string and return it.
return fromEncrypt;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
#endregion
附参数
byte[] b = Encoding.UTF8.GetBytes(Source);
byte[] IV = Encoding.UTF8.GetBytes("12345678");
byte[] Key = KeyBytes;
由于测试用密钥始终是一个值,就做成了BYTE[]常量之前有怀疑过是不是密钥解出来的字节数组与对方不一致结果我使用二楼的仁兄提供的方法得到的值与对方对比了一下,发现是一样的