将对称和非对称加密与可序列化对象相结合 (.NET Basic)
Combining Symmetric and Asymmetric Encryption with Serializeable Object (.NET Basic)
想问一下我的许可算法,我创建了一些代码来使用对称密钥 (Rijndael) 加密序列化对象,然后使用非对称密钥 (RSA) 加密对称密钥。数据使用 Public-APP 密钥加密,但使用 Private-LS 密钥签名。然后将RSA加密的密钥、RSA加密的IV、Rijndael加密的数据和签名数据放入一个序列化对象中,序列化并写入文件。但是当我加载数据来验证它时,它总是无法验证数据(使用verifydata)。当我跳过验证步骤到反序列化步骤时,它总是抛出异常
System.Runtime.Serialization.SerializationException: 'End of Stream encountered before parsing was completed.'
这是创建文件的代码
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
刚刚解决了它,我通过使用 AES 更改了加密和解密(对称)的方式,然后在从流中获取数据后添加 .FlushFinalBlock。对于签名,我没有使用 .signdata,而是使用 SignHash。
想问一下我的许可算法,我创建了一些代码来使用对称密钥 (Rijndael) 加密序列化对象,然后使用非对称密钥 (RSA) 加密对称密钥。数据使用 Public-APP 密钥加密,但使用 Private-LS 密钥签名。然后将RSA加密的密钥、RSA加密的IV、Rijndael加密的数据和签名数据放入一个序列化对象中,序列化并写入文件。但是当我加载数据来验证它时,它总是无法验证数据(使用verifydata)。当我跳过验证步骤到反序列化步骤时,它总是抛出异常
System.Runtime.Serialization.SerializationException: 'End of Stream encountered before parsing was completed.'
这是创建文件的代码
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
刚刚解决了它,我通过使用 AES 更改了加密和解密(对称)的方式,然后在从流中获取数据后添加 .FlushFinalBlock。对于签名,我没有使用 .signdata,而是使用 SignHash。