问题描述
(方法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=771but 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#获得许可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!