RSA登录C#获得许可 [英] RSA signing in C# for licensing

查看:108
本文介绍了RSA登录C#获得许可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(方法2) 我需要制定一种软件激活机制.所以我最终想到了这个方案:应用程序根据计算机的硬件创建一个唯一的ID.买家将此ID通过电子邮件发送给我.我用我的私钥对其进行签名,然后将签名后的字符串发送回去.应用会验证字符串(使用包含的公钥对其进行解码,并将其与硬件ID进行比较).

(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).

到目前为止,我已经完成了硬件ID,并且已经用openssl创建了密钥(1024位),这是两个文件private.pem和public.pem.

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.

我尝试应用 http://www.christian-etter.de中描述的解决方案/?p = 771 但是验证总是失败.

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

代码:

    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";
    }

推荐答案

您正在将某些任意字节视为UTF-8编码的字符串(SignedData),这是不正确的,因为并非所有字节序列都有效.我怀疑编码器抛出了无效字节,导致验证失败.您应该使用Base64编码将二进制数据保留为字符串格式,而不会丢失任何内容.因此:

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);

成为

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

同样,在验证过程中,您需要使用Convert.FromBase64String来获取SignedData.可以对CompID使用UTF-8,因为它是字符串数据,您需要将其转换为二进制形式进行签名.

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.

这篇关于RSA登录C#获得许可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆