首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MemoryStream:编码

MemoryStream:编码
EN

Stack Overflow用户
提问于 2015-06-29 14:40:59
回答 1查看 1K关注 0票数 1

我试图使用X509证书的公钥和私钥加密一个非常长的文本。具体来说,我正在尝试复制这个MSDN代码:https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.publickey(v=vs.90).aspx

但是,我不想加密一个文件,而是要加密一个字符串。因此,我正在尝试修改代码以使用MemoryStreams。

问题是,每次我试着读流的内容,它都有奇怪的字符。因此,当我试图调用一个webservice (asmx)并将密码文本发送给它时,它会崩溃。

这是我的密码。我试过使用UTF32,UTF8,UTF7和ASCII。

代码语言:javascript
复制
Private Shared Function encryptText(ByVal token As String, ByVal rsaPublicKey As Security.Cryptography.RSACryptoServiceProvider) As String
    Dim aesManaged As New Security.Cryptography.AesManaged()
    Dim transform As Security.Cryptography.ICryptoTransform = Nothing
    Dim outStreamEncrypted As Security.Cryptography.CryptoStream = Nothing
    Dim outFsaux As New IO.MemoryStream()
    Dim outFs As New IO.StreamWriter(outFsaux, Text.Encoding.ASCII)
    Dim inFs As New IO.MemoryStream(Text.Encoding.ASCII.GetBytes(token))
    Dim cipherText As String = String.Empty


    Try
        aesManaged.KeySize = 256
        aesManaged.BlockSize = 128
        aesManaged.Mode = Security.Cryptography.CipherMode.CBC

        Dim keyFormatter As New Security.Cryptography.RSAPKCS1KeyExchangeFormatter(rsaPublicKey)
        Dim keyEncrypted As Byte() = keyFormatter.CreateKeyExchange(aesManaged.Key, aesManaged.GetType())

        Dim LenK(3) As Byte
        Dim LenIV(3) As Byte

        Dim lKey As Integer = keyEncrypted.Length
        LenK = BitConverter.GetBytes(lKey)
        Dim lIV As Integer = aesManaged.IV.Length
        LenIV = BitConverter.GetBytes(lIV)

        outFs.Write(LenK)
        outFs.Write(LenIV)
        outFs.Write(keyEncrypted)
        outFs.Write(aesManaged.IV)

        transform = aesManaged.CreateEncryptor()

        outStreamEncrypted = New Security.Cryptography.CryptoStream(outFs.BaseStream, transform, Security.Cryptography.CryptoStreamMode.Write)
        Dim count As Integer = 0
        Dim offset As Integer = 0

        Dim blockSizeBytes As Integer = aesManaged.BlockSize / 8
        Dim data(blockSizeBytes) As Byte
        Dim bytesRead As Integer = 0

        Do
            count = inFs.Read(data, 0, blockSizeBytes)
            offset += count
            outStreamEncrypted.Write(data, 0, count)
            bytesRead += blockSizeBytes
        Loop While count > 0

        inFs.Flush()
        outStreamEncrypted.FlushFinalBlock()

        outFsaux.Position = 0
        cipherText = System.Convert.ToBase64String(outFsaux.ToArray())
    Finally
        If inFs IsNot Nothing Then inFs.Dispose()
        If outFs IsNot Nothing Then outFs.Dispose()
        If outStreamEncrypted IsNot Nothing Then outStreamEncrypted.Dispose()
        If transform IsNot Nothing Then transform.Dispose()
    End Try

    Return cipherText
End Function

升级:

谢谢你的帮助。我也更新了上面的代码。

现在我可以正确地加密文本了。然而,我仍然需要帮助,以适应解密方法。它在尝试创建变量KeyDecrypted时崩溃。

我知道问题在于,在加密方法上,它在密码字符串开始时加载一些信息,解密方法在Base64转换后无法正确恢复。

代码语言:javascript
复制
  Private Shared Function decryptText(ByVal token As String, ByVal rsaPrivateKey As Security.Cryptography.RSACryptoServiceProvider) As String
    Dim aesManaged As New Security.Cryptography.AesManaged()
    Dim inFs As IO.MemoryStream = New IO.MemoryStream(Convert.FromBase64String(token))
    Dim outFs As New IO.MemoryStream
    Dim outStreamDecrypted As Security.Cryptography.CryptoStream = Nothing

    Dim decipherText As String = String.Empty

    aesManaged.KeySize = 256
    aesManaged.BlockSize = 128
    aesManaged.Mode = Security.Cryptography.CipherMode.CBC

    Dim LenK() As Byte = New Byte(4 - 1) {}
    Dim LenIV() As Byte = New Byte(4 - 1) {}


    inFs.Seek(0, IO.SeekOrigin.Begin)
    inFs.Seek(0, IO.SeekOrigin.Begin)
    inFs.Read(LenK, 0, 3)
    inFs.Seek(4, IO.SeekOrigin.Begin)
    inFs.Read(LenIV, 0, 3)

    Dim lengthK As Integer = BitConverter.ToInt32(LenK, 0)
    Dim lengthIV As Integer = BitConverter.ToInt32(LenIV, 0)

    Dim startC As Integer = lengthK + lengthIV + 8
    Dim lenC As Integer = (CType(inFs.Length, Integer) - startC)

    Dim KeyEncrypted() As Byte = New Byte(lengthK - 1) {}
    Dim IV() As Byte = New Byte(lengthIV - 1) {}

    inFs.Seek(8, IO.SeekOrigin.Begin)
    inFs.Read(KeyEncrypted, 0, lengthK)
    inFs.Seek(8 + lengthK, IO.SeekOrigin.Begin)
    inFs.Read(IV, 0, lengthIV)

    Dim KeyDecrypted As Byte() = rsaPrivateKey.Decrypt(KeyEncrypted, False)
    Dim transform As Security.Cryptography.ICryptoTransform = aesManaged.CreateDecryptor(KeyDecrypted, IV)


    Dim count As Integer = 0
    Dim offset As Integer = 0

    Dim blockSizeBytes As Integer = aesManaged.BlockSize / 8
    Dim data(blockSizeBytes) As Byte

    inFs.Seek(startC, IO.SeekOrigin.Begin)

    outStreamDecrypted = New Security.Cryptography.CryptoStream(outFs, transform, Security.Cryptography.CryptoStreamMode.Write)
    Do
        count = inFs.Read(data, 0, blockSizeBytes)
        offset += count
        outStreamDecrypted.Write(data, 0, count)
    Loop While count > 0

    outFs.Position = 0
    Using rd As New IO.StreamReader(outFs)
        decipherText = rd.ReadToEnd()
    End Using

    Return decipherText
End Function
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-29 14:49:54

密码文本将包含不可打印的字符,因为它将对每个字节使用从0到255的整个范围。如果您想以字符串的形式发送密码文本,那么我将首先对密码文本进行base64编码。

变化

代码语言:javascript
复制
rd = New IO.StreamReader(outFsaux, Text.Encoding.ASCII)
cipherText = rd.ReadToEnd()

代码语言:javascript
复制
cipherText = System.Convert.ToBase64String(outFsaux.ToArray())

代码语法可能有点错误,因为我不使用VB编程。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31118590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档