需要BouncyCastle .net版 下面是项目中用到的证书操作类,通过该类可以生成用户证书cer文件 和证书安装文件pfx文件,并生成认证原文。
public static class CaOperator { /// <summary> /// 根证书 /// </summary> public static readonly X509Certificate RootCert = new X509CertificateParser().ReadCertificate(Encoding.Default.GetBytes( "-----BEGIN CERTIFICATE-----\n" + "MIIBrDCCARWgAwIBAgIBATANBgkqhkiG9w0BAQUFADAcMRowGAYDVQQDDBHlronl\n" + "hahDQeagueivgeS5pjAgFw0xMzA4MTQxNzAwMTBaGA8yMDYzMDgxNjE3MDAxMFow\n" + "HDEaMBgGA1UEAwwR5a6J5YWoQ0HmoLnor4HkuaYwgZ0wDQYJKoZIhvcNAQEBBQAD\n" + "gYsAMIGHAoGBAIVzPUIiMfkLyDCoyAOKOhoSAjkW8X6GJK7DiLL5cC9R2iWhGB+p\n" + "lYWlaFC7MWK0HW7Dk3FygsbZcJXSe41npyY2MUUiXJ8GYj8H9JZ3dlLTKwAUbeen\n" + "/WtnpJStj5JqeeXz0po4huq7xExThxSuT7dNiC58Qmi977j7EYe5/K6vAgEDMA0G\n" + "CSqGSIb3DQEBBQUAA4GBABEdxlmihCWuB7J0pZ602Q6U/tlaiC5r9m03H21CoJG1\n" + "slryxg8Oy365/KKyysYIzx9VplT1D0dC+A3Gsn+DSGIb3j7UDXymkd03KbBHNe2C\n" + "ZLrAuesQIzOyv/sea/Mqs0jMwfJQROPSxEgWRHJBjf+kKzjSwqMWhl6Rvq84WkJ0\n" + "-----END CERTIFICATE-----")); /// <summary> /// 根证书私钥 /// </summary> private static readonly AsymmetricKeyParameter RootKey = PrivateKeyFactory.CreateKey(Convert.FromBase64String( "MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAIVzPUIiMfkLyDCoyAOKOhoSAjkW8X6GJK7DiLL5cC9R2iWhGB+" + "plYWlaFC7MWK0HW7Dk3FygsbZcJXSe41npyY2MUUiXJ8GYj8H9JZ3dlLTKwAUbeen/WtnpJStj5JqeeXz0po4huq7xExThxSuT7dNiC58" + "Qmi977j7EYe5/K6vAgEDAoGAWPd+LBbL+10wIHCFV7F8EWFW0Ln2VFltydewd1D1dOE8GRYQFRu5A8Oa4HzLlyK+Sde3oPcB2eZLDox" + "SXkUaGHnC0IhtBwLB1LWHdt1fSPHE/VpdV5ktdkImrBJbeGtnZ5lD7KHLjb9JlnS7UB7QtGlQgkY9fNZFVoKuWwUNI3sCQQDy6Jsl/" + "WC4lwXLxxgnTxBGR9tiuNUrFJ7sN3dqmWjl68WarEZ8yKIGf+IVwRAOezbppmLor9dmd1/hz/QEm0XtAkEAjKRxL7uzyah6K+JMBBhVIj" + "uoqikPFySbGDMbJ2z043ME80BwyQz0FlYIjq0McZtxxekIKjZWFhBXVTwLLc2ziwJBAKHwZ26o6yW6A90vZW+KCtmFPOx7OMdjFJ16T" + "5xmRe6dLmcdhFMwbARVQWPWCrRSJJvEQfB1OkRPlUE1TVhng/MCQF3C9h/Sd9vFpsfsMq1ljhbScHFwtLoYZ2V3Z2+d+JeiA0zVoIY" + "IormOsF8eCEu89oPwsBwkOWQK5ON9XMkzzQcCQGnW8f/Z4Am8llagjpEGH3XXWPDqymj/4EbMDrN2e9KRq1QL1cmR2uH+Ek6qvZdmmtM" + "xFo6wZQ5wlX4hNTYqNfQ=")); /// <summary> /// 验证用户证书是否由CA 机构颁发 /// </summary> /// <param name="privKeyStr">私钥字符串</param> /// <param name="x509CertStr">证书字符串</param> /// <returns></returns> public static bool VeryifyX509(string privKeyStr, string x509CertStr) { try { var certObj = new X509CertificateParser().ReadCertificate(new MemoryStream(Encoding.Default.GetBytes(x509CertStr))); var privKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privKeyStr)); //公钥 私钥是否相等 var pubKey = (RsaKeyParameters)certObj.GetPublicKey(); certObj.Verify(pubKey); return pubKey.Exponent.Equals(privKey.PublicExponent); } catch { return false; } } /// <summary> /// 生成证书 /// </summary> /// <param name="user">用户对象</param> /// <param name="serialNumber">证书序列号</param> /// <param name="startDate">生效日期</param> /// <param name="endDate">过期日期</param> /// <param name="algorithm">算法 "SHA1WITHRSAENCRYPTION" 等等</param> /// <param name="keyLength">密钥长度 1024 2048 4096</param> /// <param name="useAge">用途 1 签名 2 交换 3 两者</param> /// <param name="privKeyStr">私钥字符串</param> /// <param name="x509CertStr">证书字符串</param> public static void NewX509Cert(Users user, BigInteger serialNumber, DateTime startDate, DateTime endDate, string algorithm, int keyLength, int useAge, out string privKeyStr, out string x509CertStr) { var r = new RsaKeyPairGenerator(); r.Init(new RsaKeyGenerationParameters( BigInteger.ValueOf(3), new SecureRandom(), keyLength, //密钥长度 25)); var keys = r.GenerateKeyPair(); var certGen = new X509V3CertificateGenerator(); certGen.Reset(); certGen.SetSerialNumber(serialNumber); certGen.SetIssuerDN(RootCert.SubjectDN);//颁发者 certGen.SetNotBefore(startDate); certGen.SetNotAfter(endDate); certGen.SetSubjectDN(RawToX509Name(user));//颁发给 certGen.SetPublicKey(keys.Public); //ca签名算法 certGen.SetSignatureAlgorithm(algorithm); //根证书 certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(RootCert)); certGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true)); certGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(keys.Public)); //密钥用途 int iuseAge; switch (useAge) { case 1: iuseAge = KeyUsage.DigitalSignature; break; case 2: iuseAge = KeyUsage.DataEncipherment; break; default: iuseAge = KeyUsage.DigitalSignature | KeyUsage.DataEncipherment; break; } certGen.AddExtension(X509Extensions.KeyUsage, true,new KeyUsage(iuseAge)); //使用根证书私钥来签名证书 这样客户端安装根证书后 可验证证书的合法性 var cert = certGen.Generate(RootKey); x509CertStr = RawCert(cert); privKeyStr = RawPrivateKey(keys); } /// <summary> /// 生成Pfx密钥文件 /// </summary> /// <param name="privKeyStr">私钥</param> /// <param name="x509CertStr">证书</param> /// <param name="pwd">密码</param> /// <returns>pfx文件</returns> public static string NewX509Pfx(string privKeyStr, string x509CertStr, string pwd) { var certObj = new X509CertificateParser().ReadCertificate(new MemoryStream(Encoding.Default.GetBytes(x509CertStr))); var privKey = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privKeyStr)); var certEntry = new X509CertificateEntry(certObj); var store = new Pkcs12StoreBuilder().SetUseDerEncoding(true).Build(); store.SetCertificateEntry("安全CA用户身份证书", certEntry); //设置证书 store.SetKeyEntry("安全CA用户身份证书", new AsymmetricKeyEntry(privKey), new[] { certEntry }); //设置私钥 using (var tx = new MemoryStream()) { store.Save(tx, pwd.ToCharArray(), new SecureRandom()); return Convert.ToBase64String(tx.ToArray()); } } /// <summary> /// /// </summary> /// <param name="user"></param> /// <returns></returns> private static X509Name RawToX509Name(Users user) { var attrs = new Hashtable(); IList order = new ArrayList(); attrs[X509Name.OU] = user.Unit == null ? string.Empty : user.Unit.FullUnitName; attrs[X509Name.CN] = user.UserNameWithAlias + "用户证书";//证书名字 attrs[X509Name.O] = SettingCopyright.Organization; attrs[X509Name.C] = "Zh"; attrs[X509Name.UID] = user.UID.ToString(CultureInfo.InvariantCulture); attrs[X509Name.T] = user.UserName; order.Add(X509Name.OU); order.Add(X509Name.CN); order.Add(X509Name.O); order.Add(X509Name.C); order.Add(X509Name.UID); order.Add(X509Name.T); return new X509Name(order, attrs); } /// <summary> /// 生成私钥base64字符串 /// </summary> /// <param name="x509CertStr">证书字符串</param> /// <returns>私钥字符串</returns> private static string RawPrivateKey(AsymmetricCipherKeyPair x509CertStr) { var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(x509CertStr.Private); return Convert.ToBase64String(privateKeyInfo.ToAsn1Object().GetDerEncoded()); } /// <summary> /// 生成证书 /// </summary> /// <param name="v3Cert">证书对象</param> /// <returns>证书字符串</returns> private static string RawCert(X509Certificate v3Cert) { string cert; using (var tx = new StringWriter()) { var pemWriter = new PemWriter(tx); pemWriter.WriteObject(v3Cert); pemWriter.Writer.Flush(); cert = tx.ToString(); } return cert; } /// <summary> /// 生成认证原文并保存到数据库 /// </summary> /// <param name="session">nhibernate session对象</param> /// <param name="user">用户对象</param> /// <param name="cert">证书对象</param> /// <returns>生成认证原文</returns> public static string NewOriginalCode(ISession session,Users user, CaCertificate cert) { var guid = Guid.NewGuid().ToString().Replace("-", ""); //前32位为guid 后面的为用户密码 guid +=user.Pwd; guid = guid.ToLower(); var caRandom = new CaRandom { UID = cert.UID, Random = guid }; session.SaveOrUpdate(caRandom); session.Flush(); return MacAtivex.EnPubKey(guid, cert.Cert); } /// <summary> /// 生成认证用户 认证原文 /// </summary> /// <param name="session"></param> /// <param name="uid"></param> /// <param name="code"></param> /// <returns></returns> public static bool VerifyOriginalCode(ISession session, int uid, string code) { var r = session.QueryOver<CaRandom>().Where(o => o.UID == uid) .Take(1).SingleOrDefault(); return r != null && r.Random.Equals(code); } }