【发布时间】:2017-02-06 11:20:28
【问题描述】:
我有一个使用 C++ 中的 openSSL 生成的密钥对,我用它来签署消息以通过严格使用 RSACryptoServiceProvider(没有 BouncyCastle 等)的 C# 服务器进行身份验证。我使用 PKCS#1 SHA256 生成签名。然后签名以十六进制形式与公钥一起传输。问题是签名无法在服务器上验证。 我已经尝试删除标头“-----BEGIN RSA PUBLIC KEY-----”等等。但是还没有结果。生成密钥对和签名的c++代码是:
RSA *keypair = NULL;
bne = BN_new();
int ret = 0;
ret = BN_set_word(bne, ea);
keypair = RSA_new();
RSA_generate_key_ex(keypair , 2048, bne, NULL);
SHA256((unsigned char*)msg, strlen(msg) + 1, hash);
RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH, sign,&signLen, keypair);
我已经使用 BIO 在字符缓冲区中收集了公钥,并将签名数据转换为十六进制字符串以传输到 c#。但是,我尝试通过编写示例表单应用程序以及在 c++ 上验证的签名和公钥来复制服务器,我已将它们硬编码为 c# 示例的输入。但它们也失败了。 谁能帮我找出可能的原因或谬误的领域是什么?
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.ImportParameters(rsParam);
UTF8Encoding encoding = new UTF8Encoding();
byte[] datax = encoding.GetBytes(data);
byte[] sigx = encoding.GetBytes(sig);
SHA256Managed sha256 = new SHA256Managed();
byte[] hash = sha256.ComputeHash(datax);
iRes= RSA.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA256"), sigx);
“数据”被传递,“sig”也是一个硬编码值,“rsParam”是使用用于生成“sig”的硬编码公钥创建的。公钥到rsParam的转换代码为:
pubkey = Convert.FromBase64String(pemString);
RSAParameters rsParam = RSA.ExportParameters(false);
rsParam .Modulus = pubkey;
RSA.ImportParameters(rsParam );
我写这段代码只是为了了解基本的 C# 密码系统是如何工作的,以便对实际问题的研究有所帮助。
【问题讨论】:
-
您应该分享您是如何进行验证的,包括使用硬编码输入。
-
SHA256((unsigned char*)msg, strlen(msg) + 1, hash);- C# 默认使用 UTF-16,所以如果你盲目地切换到 C#,你会遇到问题。你真的需要展示你的代码。 -
我没有实际的服务器代码,如果我有的话,我会弄清楚谬误的范围是什么,我在通过网络查看帖子后编写了一个基本的 c# 代码,因为 c# 不是我的专业知识,我不知道它与实际的服务器代码有多相似,但是我正在分享我用 c# 编写的内容
标签: c# c++ openssl cryptography rsa