.NET Framework 4.7.2中调用RSA SignData时出现“密钥集不存在”异常
解决RSA签名时"Keyset does not exist"异常的方案
你的核心问题是错误地将完整PKCS#8格式的私钥字节直接赋值给RSAParameters.D字段,私钥包含多个参数(D、P、Q、DP等),不能单独拆分赋值。以下是修正后的实现:
修正后的签名生成函数
public static string GenerateLicenseFromUserInfo(UserLicense info) { // 从Base64解码PKCS#8格式的私钥 byte[] privateKeyBytes = Convert.FromBase64String("MIICXAIBAAKBgQC8IG4CySTEOZhmDwlTdR4Yd6xoqoJGsfze/RvrZgY72HAuWK0Y3DKrNdFiM+Z2O1weArCyoTbGsZ7UcxhCFKQLSsHooZveQTTHDHvm7cIts8jEMDw/xbPDrMQH/vYjRshNo8vOsVwxQELVzvrMA7+A/3ITKvbL0PTSDxxMcHRQDwIDAQABAoGAUNNqEH5U8o2AQZECQ74U0RRRmaJwWGlOKIv8e9WYpgumnvLwY7bvegmkTRnZUUDNogMr4YNMIm/bupE8gd+WXpo8TrHoFDNYFGB07eAnDR/ZNcSboBLGw9JKnRCD8kZ2QYwmH/wKdJL2VppC+ooVit2AcDWeCh9pPl8gF5R054kCQQDwxfnogy19yEF6eXEBQD4um/nDUbjRaudyc/i16H6SBw1+q/sQhX/QArgDwxnU5vfUWRZ4BQGw6IlQWYNzbxuzAkEAyAYgCRIWu+lWbJEErLg4gGq4D7+B3kP7SP3+QU6SBL/eVwqtgSiWUEjB84jlu73u9eqcsDJMfVF3WxnAaOQcNQJAY7vuQBUOY/ruvJfPapA88bukYvbYEs8wniVR0bBDtaN8QItmzTovbm+h39USPzGJWQmqF/8i6y/3qTPbEpbkpwJAWzrH87snWU+EloHSEwD27ENAbhZXokt5WgJWq+ytFrN4MlTxa75aSIXWyD/BIE7xpYH7MzXNwz6b5JYrNuwLnQJBAIChHs1sxLfp0HPKnPtMEJDmYlRmM176HKywg7q77yyij2K/90ijjgSG8YrXkeLrDBieCbMdxuruevZ+yBQPhr4="); // 使用RSA.Create()替代RSACryptoServiceProvider,避免CSP密钥容器问题 using var rsa = RSA.Create(); // 直接导入完整的PKCS#8私钥 rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _); string userInfo = info.ToString(); byte[] userInfoBytes = Encoding.UTF8.GetBytes(userInfo); // 签名数据 byte[] signature = rsa.SignData(userInfoBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); return Convert.ToBase64String(signature); }
修正后的验证函数
public static bool VerifyLicenseFromUserInfo(string receivedLicenseKey, UserLicense info) { byte[] publicKeyBytes = Convert.FromBase64String("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8IG4CySTEOZhmDwlTdR4Yd6xoqoJGsfze/RvrZgY72HAuWK0Y3DKrNdFiM+Z2O1weArCyoTbGsZ7UcxhCFKQLSsHooZveQTTHDHvm7cIts8jEMDw/xbPDrMQH/vYjRshNo8vOsVwxQELVzvrMA7+A/3ITKvbL0PTSDxxMcHRQDwIDAQAB"); using var rsa = RSA.Create(); // 导入X.509格式的公钥 rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _); string userInfo = info.ToString(); byte[] userInfoBytes = Encoding.UTF8.GetBytes(userInfo); byte[] receivedSignature = Convert.FromBase64String(receivedLicenseKey); return rsa.VerifyData(userInfoBytes, receivedSignature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); }
关键说明
- 你的私钥是PKCS#8格式,公钥是X.509 SubjectPublicKeyInfo格式,不需要手动拆分RSAParameters的各个字段,直接用
ImportPkcs8PrivateKey和ImportSubjectPublicKeyInfo即可完整导入密钥。 - 使用
RSA.Create()替代RSACryptoServiceProvider,它是.NET标准的RSA实现,避免了传统CSP密钥容器可能带来的"Keyset does not exist"问题。 - 用
using语句包裹RSA对象,确保资源正确释放。
内容的提问来源于stack exchange,提问作者Hasan H
相关产品推荐
相关产品推荐

