RSA签署C#以获得许可

时间:2015-01-22 21:39:48

标签: c# rsa sign rsacryptoserviceprovider

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

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

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

代码:

    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 个答案:

答案 0 :(得分:1)

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

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。可以将UTF-8用于CompID,因为它是您需要转换为二进制形式进行签名的字符串数据。