RSA signing in C# for licensing

本秂侑毒 提交于 2019-12-13 09:13:45

问题


(Approach #2) I need to make a software activation mechanism. So i ended up with this scheme: App creates a unique id, based on computer's hardware. Buyer emails this id to me. I sign it with my private key and i send back the signed string. App verifies string (decodes it with contained public key and compares it with hardware id).

So far i am done with hardware id and i have created the keys (1024bit) with openssl, that's two files private.pem and public.pem.

I tried to apply the solution described in http://www.christian-etter.de/?p=771 but verification always fails.

The code:

    private void Generate_Click(object sender, EventArgs e)
    {
        byte[] SignedData;
        byte[] UnsignedData = Encoding.UTF8.GetBytes(CompID.Text);

        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {
            rsa.PersistKeyInCsp = false;
            rsa.LoadPrivateKeyPEM(PrivateKey.Text);
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
                SignedData = rsa.SignData(UnsignedData, sha1);
            ActCode.Text = Encoding.UTF8.GetString(SignedData, 0, SignedData.Length);
        }
    }

    //--------------------------------------------------------------------

    private void Verify_Click(object sender, EventArgs e)
    {
        byte[] UnsignedData = Encoding.UTF8.GetBytes(CompID.Text);
        byte[] SignedData = Encoding.UTF8.GetBytes(ActCode.Text);
        bool VerifOK;

        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {
            rsa.PersistKeyInCsp = false;
            rsa.LoadPublicKeyPEM(PublicKey.Text);
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
                VerifOK = rsa.VerifyData(UnsignedData, sha1, SignedData);
        }
        if (VerifOK) verif.Text = "verification ok";
        else verif.Text = "verification error";
    }

回答1:


You are treating some arbitrary bytes as a UTF-8 encoded string (SignedData) This is incorrect because not all byte sequences are valid. I suspect the encoder is throwing out the invalid bytes, causing verification to fail. You should use Base64 encoding to preserve the binary data in a string format without losing anything. So this:

using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
    SignedData = rsa.SignData(UnsignedData, sha1);
ActCode.Text = Encoding.UTF8.GetString(SignedData, 0, SignedData.Length);

becomes

using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
    SignedData = rsa.SignData(UnsignedData, sha1);
ActCode.Text = Convert.ToBase64String(SignedData);

Likewise during verification you need to use Convert.FromBase64String to get the SignedData. It is OK to use UTF-8 for the CompID because it is string data that you need converted to a binary form for signing.



来源:https://stackoverflow.com/questions/28099187/rsa-signing-in-c-sharp-for-licensing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!