-1

Wanna ask about my licensing algorithm, I create some code for encrypt a serialize object with symmetric key (Rijndael) and then encrypt the symmetric key with asymmetric key (RSA). Data is encrypt with Public-APP key but sign with Private-LS key. Then put RSA-encrypted key, RSA-encrypted IV, Rijndael-encrypted data, and signdata into an serialize object, serialize it and put to file. But when I load the data to verified it, it always failed to verified data (using verifydata). When I skip the verifying step to deserializing step, it always throw exception

System.Runtime.Serialization.SerializationException: 'End of Stream encountered before parsing was completed.'

this is code for creating file

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

This is for reading file

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

and this is what i use for symmetric encryption

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
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • The whole premise of what you are creating doesn't make sense... There's also a lot of security issues with your existing code. And you haven't provided the exception you're receiving either. Post a [mcve] of the issue, there's too much code. – Luke Joshua Park Apr 01 '18 at 03:43
  • I try to encrypt an object (about 600-1500 KB size) with RSA, but I've read that cost high processing, and RSA has limited size. It said better use symmetric to encrypt data and encrypt the symmetric-key with RSA. The problem is when I want to verify the sign data it always throw false condition, and when i just skip the verify step and directly deserialize it, it throw System.Runtime.Serialization.SerializationException: 'End of Stream encountered before parsing was completed.' Sorry for long code, I just don't know what cause it. Thank you – RhapEskies Apr 01 '18 at 03:57
  • Crypto and Licensing are very complex topics and the model of what happens where and what degree of protection you are after are important and not at all covered in the very brief description. If you are encrypting something on the client then anyone can trivially decrypt it and change stuff. Also, a new version of your app will not be able to read an old file. A better model is for you (or a web service) to create a license from some info and the client app simply validates it. – Ňɏssa Pøngjǣrdenlarp Apr 01 '18 at 16:03
  • noted @Plutonix , thank you for your advice. I'm just new at crypto and licensing. I never thought it till you said "new app will not be able to read an old file" – RhapEskies Apr 03 '18 at 13:02

1 Answers1

0

Just solved it, I change how I encrypt and decrypt (symetric) by using AES and then adding .FlushFinalBlock after getting the data from stream. And for signature, rather than using .signdata, I use SignHash.