Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在VB.NET中,将AES密钥和加密数据写入同一个内存流不起作用_Vb.net_Security_Cryptography_Encryption Symmetric - Fatal编程技术网

在VB.NET中,将AES密钥和加密数据写入同一个内存流不起作用

在VB.NET中,将AES密钥和加密数据写入同一个内存流不起作用,vb.net,security,cryptography,encryption-symmetric,Vb.net,Security,Cryptography,Encryption Symmetric,我试图使用对称加密来加密一些数据,并将解密数据所需的密钥存储在内存流中。(虽然我知道单凭这一点是非常愚蠢的安全措施,但我将使用RSA加密对称密钥。不过,现在,我正试图让这一部分正常工作。) 我正在使用FileHelpers库解析我的分隔符(分号,因为我不相信数据中会有分号)的数据。不幸的是,在我的解密函数中,当解析时,它只返回一条记录。而且,如果我显示在这个函数末尾创建的整个加密数据字符串,它似乎没有使用多个记录 我想知道当我创建新的加密流时,它是否默认为内存流的开头,所以当我写入加密数据时,它

我试图使用对称加密来加密一些数据,并将解密数据所需的密钥存储在内存流中。(虽然我知道单凭这一点是非常愚蠢的安全措施,但我将使用RSA加密对称密钥。不过,现在,我正试图让这一部分正常工作。)

我正在使用FileHelpers库解析我的分隔符(分号,因为我不相信数据中会有分号)的数据。不幸的是,在我的解密函数中,当解析时,它只返回一条记录。而且,如果我显示在这个函数末尾创建的整个加密数据字符串,它似乎没有使用多个记录

我想知道当我创建新的加密流时,它是否默认为内存流的开头,所以当我写入加密数据时,它会覆盖我刚刚写入内存流的数据。你认为那是对的吗

谢谢你的帮助

Private Function Encrypt(ByVal data As String) As String
    Dim utf8 As New UTF8Encoding
    ' Convert string data to byte array
    Dim inBytes() As Byte = utf8.GetBytes(data)
    ' Create memory stream for storing the data we've manipulated
    Dim ms As New MemoryStream()

    Dim aes As New RijndaelManaged()
    aes.KeySize = 256

    Dim cs As New CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)

    ' Write key to beginning of memory stream
    ms.Write(aes.Key, 0, aes.Key.Length)
    ' Add semicolon delimiter to memory stream
    ms.Write(utf8.GetBytes(";"), 0, utf8.GetBytes(";").Length)
    ' Write IV to memory stream
    ms.Write(aes.IV, 0, aes.IV.Length)
    ' Write semicolon delimiter to memory stream
    ms.Write(utf8.GetBytes(";"), 0, utf8.GetBytes(";").Length)
    ' Ensure that the data we've just written is in the memory stream, before
    ' we add the encrypted data
    ms.Flush()

    ' Write the encrypted data
    cs.Write(inBytes, 0, inBytes.Length) ' encrypt
    cs.FlushFinalBlock()

    ' Return encrypted data as string
    Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)
End Function

为什么要写内存流?直接写入加密流,然后从内存流读回加密数据。这是AES加密的C#版本

aesEncryptor
是您的
aes.CreateEncryptor()

这可以称为:

public byte[] doEncrypt(byte[] dataToEncrypt)
{
            RijndaelManaged aesAlg = new RijndaelManaged();
            aesAlg.KeySize = AES_KEY_SIZE;
            aesAlg.GenerateKey();
            aesAlg.GenerateIV();
            aesAlg.Mode = CipherMode.CBC;
            aesAlg.Padding = PaddingMode.PKCS7;

            byte[] aesKey = aesAlg.Key;
            byte[] aesIV = aesAlg.IV;

            byte[] encryptedData = encryptWithAes(aesAlg.CreateEncryptor(), dataToEncrypt);

            //store your aesKey, aesIV, and encryptedData together however you want
}

你不应该删除带有任何字符的二进制数据,因为当你再次读取这些数据时,你必须对整个缓冲区进行编码,包括密钥和IV,一旦编码,你的delimeter就可以随意放在任何地方。而是将密钥的长度存储为一个字节,然后在之后存储密钥。当您要读回数据时,可以将第一个字节(密钥长度)作为整数读取,然后知道要读取多少才能获得密钥。这对你有意义吗?

这里是一个如何实现这一目标的快速示例。我已经包括了
加密
解密
,因为在这两方面遵循相同的模式显然很重要。我将把相关的错误检查等留给您:)


我正在将密钥和IV写入内存流,因为我想保留它,以便数据可以被解密。我的目标是每次随机生成对称密钥,然后用户用他们的RSA密钥加密。因此,我需要将symmmetric密钥与加密数据一起存储。@Sam,该内存流应仅由加密流用于向其中写入加密数据(并供您从中读取加密数据)。如果要存储IV和密钥,请使用不同的缓冲区,然后将其附加到从内存读取的加密数据中stream@Sam,添加了获取IV、密钥和加密的示例data@Petey哦我在网上搜索的日子似乎不太愉快,因为我找不到一个结合两个记忆流的例子。我会这样做吗?创建一个memorystream来保存密钥,IV.使用cryptostream创建一个memorystream来保存加密数据。创建另一个memorystream,然后将第一个memorystream的内容写入,然后将第二个memorystream的内容写入其中?@Sam,为什么要将它们保留在内存流中?尝试用“;”来划界不是一个好主意在内存流中(当您重新编码时,要尝试读取分隔符,加密的数据/密钥可能在任何地方都有“;”。最好先存储第一个字节作为密钥的长度,然后存储密钥,然后存储下一个字节作为IV的长度,然后存储IV,然后存储其余的加密数据。
public byte[] doEncrypt(byte[] dataToEncrypt)
{
            RijndaelManaged aesAlg = new RijndaelManaged();
            aesAlg.KeySize = AES_KEY_SIZE;
            aesAlg.GenerateKey();
            aesAlg.GenerateIV();
            aesAlg.Mode = CipherMode.CBC;
            aesAlg.Padding = PaddingMode.PKCS7;

            byte[] aesKey = aesAlg.Key;
            byte[] aesIV = aesAlg.IV;

            byte[] encryptedData = encryptWithAes(aesAlg.CreateEncryptor(), dataToEncrypt);

            //store your aesKey, aesIV, and encryptedData together however you want
}
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text

Module Module1

  Sub Main()
    Dim encrypted As String = Encrypt("Here is the data")
    Dim decrypted As String = Decrypt(encrypted)
    Console.WriteLine(decrypted)
    Console.ReadKey()
  End Sub

  Private Function Encrypt(clearText As String) As String
    Dim aes As New RijndaelManaged
    aes.KeySize = 256

    Using ms As New MemoryStream
      ms.WriteByte(aes.Key.Length)
      ms.Write(aes.Key, 0, aes.Key.Length)
      ms.WriteByte(aes.IV.Length)
      ms.Write(aes.IV, 0, aes.IV.Length)

      Using cs As New CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)
        Dim bytes() As Byte = Encoding.UTF8.GetBytes(clearText)
        cs.Write(bytes, 0, bytes.Length)
      End Using

      Return Convert.ToBase64String(ms.ToArray())
    End Using
  End Function

  Private Function Decrypt(cipherText As String) As String
    Dim ms As New MemoryStream(Convert.FromBase64String(cipherText))

    Dim keyLength As Byte = ms.ReadByte()
    Dim key(keyLength - 1) As Byte
    ms.Read(key, 0, keyLength)

    Dim ivLength As Byte = ms.ReadByte()
    Dim iv(ivLength - 1) As Byte
    ms.Read(iv, 0, ivLength)

    Dim dataOffset As Integer = ms.Position

    Dim aes As New RijndaelManaged()
    aes.Key = key
    aes.IV = iv

    Using cs As New CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read)
      Using sr As New StreamReader(cs, Encoding.UTF8)
        Return sr.ReadToEnd()
      End Using
    End Using
  End Function
End Module