我一直得到这个"输入数据不是一个完整的块。"解密时出错。该函数成功加密纯文本并将IV放入文本框中。我正在使用加密数据和来自文本的IV来解密原始数据,但我一直收到错误。我不知道我哪里出错了。继承我的代码
Imports System.IO 'Import file I/O tools
Imports System.Security.Cryptography 'Import encryption functionality
Imports System.Text 'Import text based processing tools`
Public Class Form1
Private Function AESEncryption(ByVal clearText As String, ByVal key As String) As String
Dim salt As String = tbpassword.Text.Insert(tbpassword.Text.Length - 1, "7?1!")
Dim Md5 As New MD5CryptoServiceProvider()
Dim Encryptionkey As Byte() = Md5.ComputeHash(Encoding.UTF8.GetBytes(key & salt))
Dim AES As New AesCryptoServiceProvider
AES.Key = Encryptionkey
AES.Mode = CipherMode.CBC
tbIV.Text = Convert.ToBase64String(AES.IV)
Dim datain() As Byte = Encoding.UTF8.GetBytes(clearText)
Dim memorystream As New MemoryStream(datain)
Dim cstream As New CryptoStream(memorystream, AES.CreateEncryptor, CryptoStreamMode.Write)
cstream.Write(datain, 0, datain.Length)
AES.Clear()
memorystream.Close()
Return Convert.ToBase64String(memorystream.ToArray())
End Function
Private Function AESdecryption(ByVal encrypteddata As String, ByVal key As String) As String
Dim salt As String = tbpassword.Text.Insert(tbpassword.Text.Length - 1, "7?1!")
Dim Md5 As New MD5CryptoServiceProvider()
Dim Encryptionkey As Byte() = Md5.ComputeHash(Encoding.UTF8.GetBytes(key & salt)) 'uses password and salt to create a hash byte array
Dim EncryptionIn() As Byte = Convert.FromBase64String(encrypteddata)
Dim AES As New AesCryptoServiceProvider
AES.Key = Encryptionkey
AES.Mode = CipherMode.CBC
AES.IV = Convert.FromBase64String(tbIV.Text)
Dim ms As New MemoryStream(EncryptionIn)
Dim cryptostream As New CryptoStream(ms, AES.CreateDecryptor, CryptoStreamMode.Read)
Dim decrypteddata() As Byte
ReDim decrypteddata(EncryptionIn.Length - 1)
cryptostream.Read(decrypteddata, 0, decrypteddata.Length)
AES.Clear()
ms.Close()
Return Convert.ToBase64String(ms.ToArray)
End Function
Private Sub btnencrypt_Click(sender As Object, e As EventArgs) Handles btnencrypt.Click
tbencrypteddata.Text = AESEncryption(tbuserdata.Text, tbpassword.Text)
End Sub
Private Sub btndecrypt_Click(sender As Object, e As EventArgs) Handles Button1.Click
tbdecrypteddata.Text = AESdecryption(tbencrypteddata.Text, tbpassword.Text)
End Sub
End Class
答案 0 :(得分:2)
除非你打算手动确保你的输入是BlockSize的倍数(以位为单位),否则一定要指定填充:
示例代码:
byte[] Process(byte[] bInput, bool decrypt = false)
{
byte[] bOutput = null;
using (var c = System.Security.Cryptography.AesCryptoServiceProvider.Create())
{
c.BlockSize = 128;
c.IV = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; // blocksize / 8 = 16 long
c.KeySize = 256;
c.Key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; // key = keysize / 8 = 32 bytes
c.Mode = System.Security.Cryptography.CipherMode.CBC;
c.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
if (decrypt)
{
using (var t = c.CreateDecryptor())
{
bOutput = t.TransformFinalBlock(bInput, 0, bInput.Length);
}
}
else
{
using (var t = c.CreateEncryptor())
{
bOutput = t.TransformFinalBlock(bInput, 0, bInput.Length);
}
}
}
return bOutput;
}
答案 1 :(得分:0)
在使用ICryptoTransform实现之前,我遇到了同样的问题:
...
Dim AES As New AesCryptoServiceProvider
AES.Key = Encryptionkey
AES.Mode = CipherMode.CBC
AES.IV = Convert.FromBase64String(tbIV.Text)
Dim transformer As ICryptoTransform = AES.CreateDecryptor()
dim trnsfrmBlock as Byte() = transformer.TransformFinalBlock(EncryptionIn, 0, EncryptionIn.Length)
Return Convert.ToBase64String(trnsfrmBlock)
答案 2 :(得分:0)
您的代码存在多个问题。
在加密功能中:
MemoryStream
,因此它以固定大小创建,无法通过将来的填充进行扩展。您应该使用New MemoryStream(datain.Length)
代替。memorystream.Close()
,然后请求memorystream.ToArray()
的内容,但没有任何明确的cstream.Close()
调用:这样最后一个块,包括填充,实际上并没有被写入memorystream
。在提取cstream.Close()
数据之前,您应该致电memorystream
。AesCryptoServiceProvider
和CryptoStream
之前释放MemoryStream
资源是非常不合逻辑的,尽管不是禁止的。在解密功能中:
decrypteddata
的数据量。您应该根据cryptostream.Read(…)
返回的实际值缩小此数组。AES.Clear()
相同的问题。Return Encoding.UTF8.GetString(decrypteddata.ToArray())
。修复这些问题后,我可以毫无错误地运行您的程序。