如何在 OFB 模式下在 C# 中使用 3DES 解密?
我昨晚发布了同样的问题,但我给出了一个非常糟糕的代码示例。希望这会让大家更容易理解我的情况。
我需要解密在 OFB 模式下使用 3DES 使用空填充加密的消息。
这是我尝试使用从网上获取的代码进行解密。
加密的消息、密钥和 IV 均被验证正确。
它会产生以下错误:
发生加密错误:指定的密钥不是该算法的有效大小。
假设代码的其他所有内容都很好,我如何更改密码模式,使其为 null 的 OFB填充?
使用系统; 使用 System.Collections.Generic; 使用系统文本;
命名空间_DESapp { 使用系统; 使用系统.安全.密码学; 使用系统文本; 使用系统.IO;
class TrippleDESCSPSample
{
static void Main()
{
try
{
int discarded;
byte[] encrypteddata = Convert.FromBase64String( "zbv67qbzN6pD2Uaog62u8WgZOcOz");
byte[] key = Convert.FromBase64String( "wSQ90YI+lAauwVVSySAi8u0P");
byte[] IV = HexEncoding.GetBytes("ac3834bfbda8eb07", out discarded);
string decrypteddata = DecryptTextFromMemory( encrypteddata, key, IV);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream(Data);
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
ICryptoTransform des = new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, des, CryptoStreamMode.Read);
//CryptoStream csDecrypt = new CryptoStream(msDecrypt,
// new TripleDESCryptoServiceProvider().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 new ASCIIEncoding().GetString(fromEncrypt);
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
public class HexEncoding
{
public HexEncoding()
{
//
// TODO: Add constructor logic here
//
}
public static byte[] GetBytes(string hexString, out int discarded)
{
discarded = 0;
string newString = "";
char c;
// remove all none A-F, 0-9, characters
for (int i = 0; i < hexString.Length; i++)
{
c = hexString[i];
if (IsHexDigit(c))
newString += c;
else
discarded++;
}
// if odd number of characters, discard last character
if (newString.Length % 2 != 0)
{
discarded++;
newString = newString.Substring(0, newString.Length - 1);
}
int byteLength = newString.Length / 2;
byte[] bytes = new byte[byteLength];
string hex;
int j = 0;
for (int i = 0; i < bytes.Length; i++)
{
hex = new String(new Char[] { newString[j], newString[j + 1] });
bytes[i] = HexToByte(hex);
j = j + 2;
}
return bytes;
}
public static bool IsHexDigit(Char c)
{
int numChar;
int numA = Convert.ToInt32('A');
int num1 = Convert.ToInt32('0');
c = Char.ToUpper(c);
numChar = Convert.ToInt32(c);
if (numChar >= numA && numChar < (numA + 6))
return true;
if (numChar >= num1 && numChar < (num1 + 10))
return true;
return false;
}
private static byte HexToByte(string hex)
{
if (hex.Length > 2 || hex.Length <= 0)
throw new ArgumentException("hex must be 1 or 2 characters in length");
byte newByte = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
return newByte;
}
}
}
}
I posted this same question last night but I gave a very poor example of code. Hopefully this will make it easier to understand my situation.
I need to decrypt messages that have been encrypted using 3DES in OFB mode with null padding.
Here's my attempt to do the decryption using code I grabbed from the web.
The encrypted message, key and IV are all verified as correct.
It produces the following error:
A Cryptographic error occurred: Specified key is not a valid size for this algorithm.
Assuming all else is well with the code, how do I change the cipher mode so it's OFB with null padding?
using System;
using System.Collections.Generic;
using System.Text;
namespace _DESapp
{
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
class TrippleDESCSPSample
{
static void Main()
{
try
{
int discarded;
byte[] encrypteddata = Convert.FromBase64String( "zbv67qbzN6pD2Uaog62u8WgZOcOz");
byte[] key = Convert.FromBase64String( "wSQ90YI+lAauwVVSySAi8u0P");
byte[] IV = HexEncoding.GetBytes("ac3834bfbda8eb07", out discarded);
string decrypteddata = DecryptTextFromMemory( encrypteddata, key, IV);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream(Data);
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
ICryptoTransform des = new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, des, CryptoStreamMode.Read);
//CryptoStream csDecrypt = new CryptoStream(msDecrypt,
// new TripleDESCryptoServiceProvider().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 new ASCIIEncoding().GetString(fromEncrypt);
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
}
public class HexEncoding
{
public HexEncoding()
{
//
// TODO: Add constructor logic here
//
}
public static byte[] GetBytes(string hexString, out int discarded)
{
discarded = 0;
string newString = "";
char c;
// remove all none A-F, 0-9, characters
for (int i = 0; i < hexString.Length; i++)
{
c = hexString[i];
if (IsHexDigit(c))
newString += c;
else
discarded++;
}
// if odd number of characters, discard last character
if (newString.Length % 2 != 0)
{
discarded++;
newString = newString.Substring(0, newString.Length - 1);
}
int byteLength = newString.Length / 2;
byte[] bytes = new byte[byteLength];
string hex;
int j = 0;
for (int i = 0; i < bytes.Length; i++)
{
hex = new String(new Char[] { newString[j], newString[j + 1] });
bytes[i] = HexToByte(hex);
j = j + 2;
}
return bytes;
}
public static bool IsHexDigit(Char c)
{
int numChar;
int numA = Convert.ToInt32('A');
int num1 = Convert.ToInt32('0');
c = Char.ToUpper(c);
numChar = Convert.ToInt32(c);
if (numChar >= numA && numChar < (numA + 6))
return true;
if (numChar >= num1 && numChar < (num1 + 10))
return true;
return false;
}
private static byte HexToByte(string hex)
{
if (hex.Length > 2 || hex.Length <= 0)
throw new ArgumentException("hex must be 1 or 2 characters in length");
byte newByte = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
return newByte;
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论