【发布时间】:2017-08-25 00:26:43
【问题描述】:
我有一个 x509 证书,其中包含存储在安全网 USB 令牌上的公钥和私钥。
我有一些数据要签名。我需要使用证书的公钥来验证签名。
使用我自己的自签名证书进行签名的最终代码:
RSACryptoServiceProvider rsa1 = (RSACryptoServiceProvider)useCertificate.PrivateKey;
byte[] digitalSignature = rsa1.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
以及使用证书公钥验证的代码:
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)useCertificate.PublicKey.Key;
Verified = rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), digitalSignature);
使用自签名证书可以正常工作。我得到的签名是 256
字节。
使用此代码获取签名然后验证的令牌,我只得到 128 字节的签名并且验证失败:
CspParameters csp = new CspParameters(1, "SafeNet RSA CSP");
csp.Flags = CspProviderFlags.UseDefaultKeyContainer;
csp.KeyNumber = (int)KeyNumber.Signature;
RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(csp);
验证码同上。
我注意到我要使用的证书是令牌中的默认值。为什么我只得到一个 128 字节的签名而不是 256?我怀疑这就是它无法验证的原因。
我的 csp 中是否需要一些其他参数和设置?
谢谢
* 基于 cmets 的更新 *
很明显,当我指定 csp.keyNumber = (int)KeyNumber.Signature 时,我使用的是 1024 位 - 但这是令牌实际返回任何内容的唯一方式。即使令牌密钥大小是 2048 位并且密钥规范是 AT_KEYEXCHANGE。当我使用我认为实际上正确的交换密钥号时,当我尝试计算签名时,系统会提示我登录,但随后出现异常“参数无效”。因此,据我所知,我需要两件事之一:
1 - 如何使用公钥来验证使用 1024 位的签名(没有令牌 - 我们需要在没有令牌的机器上验证)。
或
2 - 如何设置不正确的内容,以便我们可以通过异常 - 我认为这是更好的主意。
有没有人对我可以对这个异常做些什么或可能导致它的原因有什么建议?
完整的异常详情如下:
HResult = -2147024809 Message = 参数不正确。 堆栈跟踪
在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时) 在 System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey,Int32 keyNumber,Int32 calgKey,Int32 calgHash,Byte[] 哈希,Int32 cbHash,ObjectHandleOnStack retSignature) 在 System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash) 在 System.Security.Cryptography.RSACryptoServiceProvider.SignHash(字节 [] rgbHash,Int32 calgHash) 在 System.Security.Cryptography.RSACryptoServiceProvider.SignHash(字节 [] rgbHash,字符串 str) 在 TE.Program.Main(String[] args) 在 z:\Work\compusolve\enctest\TE\TE\Program.cs:line 77
【问题讨论】:
-
除非数据丢失,否则 128 字节签名用于 1024 位密钥而不是 2048 位密钥;即错误的密钥对。
-
这对我有帮助。我知道我的验证密钥是 2048 位密钥。因此,我将深入研究如何让令牌使用正确的密钥对。我会在这里报告。
-
我将签名的代码更改为:
RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(2048, csp);但它并没有改变结果 - 我仍然只得到 128 个字节。这应该需要使用 2048 位密钥。 -
无论我在创建 RsaCryptoServiceProvider 时指定什么,内部密钥大小都是 1024。如果我将 csp.KeyNumber 更改为
(Int)KeyNumber.Exchange而不是Signature,那么我会得到我想要的 2048 密钥大小,当我要求设备计算签名时,我得到一个异常“参数无效”。设备上的 KeySize 为 2048 位。 -
您确定可以使用密钥生成签名吗?因为 AT_KEYEXCHANGE 不是签名生成。
标签: c# cryptography rsacryptoserviceprovider