将对称和非对称加密与可序列化对象相结合(.NET Basic)

时间:2018-04-01 03:34:34

标签: .net vb.net encryption rsa rijndael

想知道我的许可算法,我创建了一些代码来加密具有对称密钥(Rijndael)的序列化对象,然后使用非对称密钥(RSA)加密对称密钥。数据使用Public-APP密钥加密,但使用Private-LS密钥进行签名。然后将RSA加密的密钥,RSA加密的IV,Rijndael加密的数据和signdata放入序列化对象,将其序列化并存档。但是,当我加载数据以验证它时,它总是无法验证数据(使用verifydata)。当我跳过验证步骤反序列化步骤时,它总是抛出异常

  

System.Runtime.Serialization.SerializationException:'在解析完成之前遇到的流结束。'

这是用于创建文件的代码

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

    varLicense = New LicenseInfo With {
        ..LICENSE INFO..
    }

    sfd.ShowDialog()
    Dim FilePath As String = sfd.FileName

    'Convert License to Byte
    Dim ms As New MemoryStream
    Dim bf As New BinaryFormatter()
    bf.Serialize(ms, varLicense)
    Dim byteLicense As Byte() = ms.ToArray
    ms.Close()

    'Generate random symetricKey
    Dim validPassChar As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()-+="
    Dim res As New StringBuilder()
    Dim rnd As New Random()
    Dim lPass As Integer = 50
    While (0 < lPass)
        res.Append(validPassChar(rnd.Next(validPassChar.Length)))
        lPass = lPass - 1
    End While

    'Generate key
    Dim rmEnc As New RijndaelManaged()
    rmEnc.BlockSize = 256
    Dim pwdGen As New Rfc2898DeriveBytes(res.ToString, 1993)
    Dim key As Byte() = pwdGen.GetBytes(rmEnc.KeySize / 8)
    Dim IV As Byte() = pwdGen.GetBytes(rmEnc.BlockSize / 8)

    'Encrypt Data License with Symetric Key
    Dim varDataEnc As Byte() = symEncrypt(key, IV, byteLicense)

    'Encrypt Symetric Key with RSA Public APP Key
    Dim RSA = New RSACryptoServiceProvider()
    RSA.FromXmlString(Project1.My.Resources.public_key_APP)
    Dim keyCipher = RSA.Encrypt(key, True)
    Dim ivCipher = RSA.Encrypt(IV, True)

    'sign the hash with RSA Private LS Key
    RSA = New RSACryptoServiceProvider()
    RSA.FromXmlString(Project1.My.Resources.private_key_LS)
    Dim hash = RSA.SignData(byteLicense, New SHA512CryptoServiceProvider)


    'initialize final license
    Dim fnLicense As New FinalLicense
    fnLicense.secret_key = keyCipher
    fnLicense.secret_IV = ivCipher
    fnLicense.data = varDataEnc
    fnLicense.hash_sign = hash

    'save license to file
    Dim fs As New FileStream(FilePath, FileMode.OpenOrCreate)
    bf.Serialize(fs, fnLicense)
    fs.Close()


    MsgBox("License Created!", vbOKOnly)

End Sub

这是用于阅读文件

Public Function LoadLicense() As Boolean

    Dim fs As New FileStream(ofd.FileName, FileMode.Open)
    Dim bf As New BinaryFormatter()
    Dim fnlLicense As FinalLicense = bf.Deserialize(fs)
    fs.Close()

    'Decrypt Symetric Key with RSA
    Dim RSA = New RSACryptoServiceProvider()
    RSA.FromXmlString(Project1.My.Resources.private_key_APP)
    Dim symKey = RSA.Decrypt(fnlLicense.secret_key, True)
    Dim symIV = RSA.Decrypt(fnlLicense.secret_IV, True)


    'Decrypt data with sym key
    Dim data As Byte() = symDecrypt(symKey, symIV, fnlLicense.data)

    'SIGNATURE CHECK
    Dim RSAX = New RSACryptoServiceProvider()
    RSAX.FromXmlString(Project1.My.Resources.public_key_LS)
    If (RSAX.VerifyData(data, New SHA512CryptoServiceProvider, fnlLicense.hash_sign)) Then
        'decapsulation
        'tried jump here but throw 
        'System.Runtime.Serialization.SerializationException: 'End of Stream encountered before parsing was completed.'
        Dim ms As New MemoryStream(data)
        ms.Position = 0
        Dim varLicense As LicenseInfo = bf.Deserialize(ms)
        ms.Close()

        Me.LICENSE_INFO = varLicense
        Return True
    Else
        Return False
    End If

End Function

这就是我用于对称加密的方法

Public Function symEncrypt(key As Byte(), IV As Byte(), data As Byte()) As Byte()

    Dim rmEnc As New RijndaelManaged()

    rmEnc.BlockSize = 256

    rmEnc.Key = key
    rmEnc.IV = IV

    Dim ms As New MemoryStream
    Dim cs As New CryptoStream(ms, rmEnc.CreateEncryptor, CryptoStreamMode.Write)
    Dim output As Byte()

    cs.Write(data, 0, data.Length)
    output = ms.ToArray

    ms.Close()

    Return output
End Function

Private Function symDecrypt(key As Byte(), iv As Byte(), data As Byte()) As Byte()
    Dim rmEnc As New RijndaelManaged()

    rmEnc.BlockSize = 256
    rmEnc.Key = key
    rmEnc.IV = iv

    Dim ms As New MemoryStream
    Dim cs As New CryptoStream(ms, rmEnc.CreateDecryptor, CryptoStreamMode.Write)
    Dim output As Byte()

    cs.Write(data, 0, data.Length)
    output = ms.ToArray

    ms.Close()

    Return output
End Function

1 个答案:

答案 0 :(得分:0)

刚刚解决了这个问题,我通过使用AES更改了加密和解密(symetric)的方式,然后在从流中获取数据后添加.FlushFinalBlock。对于签名,而不是使用.signdata,我使用SignHash。