package com.ylsoft.cert; import java.io.file; import java.io.fileInputStream; import java.io.fileoutputStream; import java.io.ioexception; import java.security.invalidkeyexception; import java.security.keypair; import java.security.keypairgorator; java.security.keystore; import java.security.keystoreexception; import java.security.nosuchalgorithmexception; import java.security.nosuchproviderexception; import java.security.privatekey; import java.security.secreandom; import java.securit java.security.signatureException; import java.security.unrecoverableyException; import java.security.cert.certificate; import java.security.cert.certificateException; import java.security.cert.x509certificate; import java.util.date; import java.util.vecteur; import; Sun.Misc.Base64Encoder; Import Sun.Security.util.ObjectIdentifier; Import Sun.Security.x509.Algorithmid; Import Sun.Security.x509.Certandkeygen; Import Sun.Security.x509 Sun.Security.x509.CertificateSerialNumber; Import Sun.Security.x509 Sun.Security.x509.KeyIdentifier; Import Sun.Security.x509.KeyUsageExtension; Import Sun.Security.x509.SubjectKeyIntifieRextension; Import Sun.Security.x509.x500Name; Import Sun.Security.x509.x500Signer; Import Sun.Security.x509.X509CERTIMPLE; Sun.Security.x509.x509certInfo; / ** * 首先生成 Ca 的根证书 , 然后有 Ca 的根证书签署生成 Scriptx 的证书 * * @Author Administrator * * / public class Genx509Cert {/ ** 提供强加密随机数生成器 (rng) * * / private SecureRandom Sr; public Genx509cert () (RNG) 算法的 SecureRandom 对象。sr = SecureRandom.getInstance ("Sha1prng", "Sun");} public void CreateCert (Certificat X509Certificate, privateKey Rootprivke {// x.509 V1 证书的抽象类。此类提供了一种访问 X.509 V1 证书所有属性的标准方式。BYTE Certytes [] = Certificate.GetEncoded (); // La classe X509Certimpl représente un X509Certimplt (certificat X509Certimpl = New X509Certimpl (certificat); // la classe X509Certinfo information.x509certinfo x509certInfo = (x509certinfo) x509certimpl.get ("x509.info"); // cette classe définit l'attribut x509key pour le certificate.x509certinfo.set ("Key", nouveau certificatx509ke CertificateCertificateExtensions CertificateExtensions = new CertificateExtensions (); CertificateExtensions.Set ("SubjectyIdentifier", new SubjectKeyIdentiErextension ((new KeyIdentifier (kp.getPublic ("Extensions", certificat ())); ///////设置 émetteur 域 x500Name émetteur = new x500Name ("cn = rootca, ou = hackwp, o = wp, l = bj, s = bj, c = cn"); x509certinfo.set ("issuer.dname", émetteur); // construit un nom à partir d'une chaîne conventionnelle, une chaîne formatée, tel // "cn = dave, ou à une convention O = Sun Microsystems, C = US ". (RFC 1779 ou RFC // Style 2253) .x500Name sujet = new x500Name ("cn = scriptx, ou = wps, o = wps, l = bj, st = bj, c = cn"); x509certinfo.set (" Signature.getInstance ("md5withrsa"); // 初始化这个用于签名的对象。如果使用其他参数再次调用此方法 , 此调用的结果将无效。signature.initsign (kp.getprivate ()); // cette classe fournit une liaison entre un objet de signature et un // a // nécessaire dans de nombreuses applications de signature X.509. X500SIGNER (Signature, émetteur); // Cette classe identifie des algorithmes, tels que les transformations cryptographiques, // chacune peut être associée à des paramètres.algorithmid algorithmid = signateur.getalgorithmid (); // cette classe définit l'algorithmid pour le certificat.x509certin Certificatealgorithmid (algorithmid)); // 开始时间 date bdate = new Date (); // 结束时间 Date edate = new Date (); // 天 小时 小时 分 毫秒 毫秒 edate.settime (bdate.gettime () + 3650 * 24l * 60l * 60l * 1000l) valid.证书的有效时间CertificateValidity certificatevalidity = new CertificateValidity(bdate, edate);x509certinfo.set("validity", certificatevalidity);// This class defines the SerialNumber attribute for the Certificate.// 设置有效期域(包含开始时间和到期时间)域名等同与x509certinfo.VALIDITYx509certinfo.set("serialNumber", new CertificateSerialNumber ((int) (new Date (). GetTime () / 1000l))); // 设置序列号域, cette classe définit la version du x509 certificate.certificateversion cv = new CertificateVersion (CertificateSion.V3); X509CertinInfo.Set (x509certinfo.version, cv); //以上是证书的基本信息 如果要添加用户扩展信息 则比较麻烦 首先要确定 Version 必须是 v3 否则不行 然后按照以下步骤 * / objetIdentifier oid = new ObjectIdentifier (new int [] {2, 5, 29, 15}); // 生成扩展域的 id 是个 int 数组 第 1 位最大 2 第 2 位最大 39 最多可以几位不明 .... userdata.length (); // 数据总长 17 位 octet f = 0x04; byte [] bs = new byte [userdata.length () + 2]; bs [0] = f; bs [1] = l; for (int i = 2; i <bs.length; i ++) {bs [i] = (byte) userdata.charat (i - 2);} extension ext = new Extension (oid, true, bs); // 生成一个 extension 对象 参数分别为 oid , 是否关键扩展 , , 型的内容值] 型的内容值 // 其中内容的格式比较怪异 其中内容的格式比较怪异 第一位是 第一位是 这里取 这里取 暂时没出错 , , 是否关键扩展 , , 位是后面的实际数据的长度 然后就是数据 然后就是数据 然后就是数据 // 密钥用法 keyUsageExtension keyusage = newusage = newusage = newusage) keyusage = newusage = newusage = newusage) keyusage = newusage eTentension Keyusage = newusage keyusage = newsage keyusage clés KeyUsageExtension (); keyUsage.set (keyUsageExtension.digital_signature, true); keyUsage.set (keyUsageExtension.non_repudiation, true); keyUsage.set (keyUsageExtension.Key_EnCiPhement, true); ObjectIdentifier (new int [] {1, 3, 6, 1,5, 5, 7, 3, 3}); vector <BjectIdentifier> vKeyoid = new Vector <BjectIdentifier> (); vKeyoid.Add (ekeyOx); ExtendedKeyUsageExtension exkeyUsage = new extendKey CertificateExtensions (); exts.set ("keyUsage", keyUsage); exts.set ("ExtendedKeyUsage", exKeyUsage); // 如果有多个 Extension 则都放入 CertificateExtensions 类中 , x509Certinfo.Set (X509CERTINFO.Extensions, exts); // 设置 extensions 域 x509cretimp X509Certimpl (x509certInfo); x509Certimpl1.sign (rootPrivkey, "MD5Withrsa"); // 使用另一个证书的私钥来签名此证书 这里使用 MD5 散列 用 用 用 用 来加密 来加密 Base64Encoder Base64 = New Base64Encoder (); FileOutStream Fos = New FileOutputtream (nouveau (nouveau File ("f: //scriptx.crt")); base64.encodeBuffer (x509Certimpl1.getEncoded (), fos); try {Certificate [] Certchain = {x509Certimpl1}; Savepfx ("scriptx", kp.getPrivate (), "123456",,, certchain, "f: //scriptx.pfx"); fileInputStream dans = new FileInputStream ("f: //scriptx.pfx"); keystore inputKeystore = keystore.getInstance ("pkcs12"); entrée InputKeyStore.getCertificate ("ScriptX"); System.out.print (cert.getPublicKey ()); privateKey privk = (privateKey) InputKeyStore.getKey ("ScriptX", "123456" .tocharArray ()); fileoutputStream privkfos = new FileOutStream (new File ("f: //scriptx.pvk")); privkfos.write (privk.getEncoded ()); System.out.print (privk); // base64.encode (key.getEncoded (), privkfos); in.close ();} catch (exception e) {// too ateriated Catch Block生成文件 x509Certimpl1.Verify (certificate.getPublicKey (), null);} / ** * 保存此根证书信息 Keystore Personal Information Exchange * @param alias * @param privkey * @param pwd * @param Certchain * @param filepath * @throws exception * / public Void Savepfx (String Alias, privatekey privily Filepath) lève une exception {// 此类表示密钥和证书的存储设施。/// 返回指定类型的 Keystore 对象。此方法从首选 Provider 开始遍历已注册安全提供者列表。返回一个封装 KeystoRespi // 实现的新 Keystore 对象 , 该实现取自第一个支持指定类型的 Provider。KeyStore outputKeystore = keystore.getinstance ("PKCS12"); SystemTyPe.println ("Keystore 类型 : :" Keystore (例如 , 驻留在硬件标记设备上的 Keystore) 或检验 // Keystore 数据的完整性。如果没有指定用于完整性检验的密码 , 则不会执行完整性检验。如果要创建空 // Keystore , 或者不能从流中初始化 Keystore , 则传递 Null 作为 Stream 的参数。注意 , 如果此 Keystore // 已经被加载 , 那么它将被重新初始化 , 并再次从给定输入流中加载。outputKeystore.Load (null, pwd.tocharay ()); // 将给定密钥 将给定密钥 已经被保护) 分配给给定别名。如果受保护密钥的类型为 // // java.security.privatekey , 则它必须附带证明相应公钥的证书链。如果底层 keystore 实现的类型为 // jks , 则必须根据 pkcs # 8 标准中的定义将 Key 编码为 // EncryptedprivateKeyInfo 。如果给定别名已经存在 , 则与别名关联的 Keystore // 信息将被给定密钥 (还可能包括证书链) 重写。outputkeystore.setkeyendry (alias, privily, pwd.tocharray (), attchain); // Keystore.privateKeyEntry pke = new // keystore.privatekeyentry (kp.getprivate (), certchain); // keystore.passwordprotection password = new // keystore.passwordprotection ("123456" .tocharArray ()); FileOutputStream (filepath); // 将此 keystore 存储到给定输出流 , 并用给定密码保护其完整性。outputKeystore.store (out, pwd.tocharay ()); out.close ();} public void Savejks (String Alias, privilyke Keystore.getInstance ("jks"); System.out.println (outputKeyStore.getType ()); outputKeyStore.load (null, pwd.tocharay ()); outputKeystore.setKeyEntry (alias.privkey, pwd.tocharay (), certificat Keystore.privateKeyEntry (kp.getPrivate (), certchain); // keystore.passwordprotection mot de passe = new // keystore.passwordprotection ("123456" .tocharay ()); // outputKeystore.Settentry ("scriptx", pke, mot de passe); fileoutputtream out new FileOutputStream (filepath); outputkeystore.store (out, pwd.tocharArray ()); out.close ();} / ** * 颁布根证书 , 自己作为 自己作为 Ca * * @throws nosuchalgorithmexception * @throws nosuchproviderexception * @throws invalidkeyxception * @throws ioException * @throws UncoverableKeyException * / public void Createrootca () lève des notesuchalgorithMexception, NosuchProviderexception, InvalidKeyException, ioException, CertificateException, SignatureException, non-CoarkeKeyException CAK = new CERTANDKEYGEN ("RSA", "md5withrsa", null); // définit la source de nombres aléatoires utilisés lors de la génération de clés de clés.cak.setrandom (sr); // génère une paire de clés publiques aléatoires, avec une clé de clé donnée.Cak.Genète (1024); // construit un nom à partir d'un nom à partir d'un nom de convention Ou = Javasoft, O = Sun Microsystems, C = US ". (Style RFC 1779 ou RFC // 2253) X500NAME SUJET = NOUVEAU X500NAME ("CN = rootca, ou = hackwp, o = wp, l = bj, s = bj, c = cn"); // renvoie un certificat X.509v3 auto-signé pour la touche publique. Le certificat // est immédiatement valide. Aucune extension.// De tels certificats sont normalement utilisés pour identifier une "Autorité de certificat //" (CA). En conséquence, ils ne seront pas toujours acceptés par // d'autres parties. Cependant, ces certificats sont également utiles lorsque vous // vous amorcez votre infrastructure de sécurité ou que vous déploiez le système // prototypes. 自签名的根证书 x509Certificate Certificate = CAK.getselfertificate (sujet, nouveau Date (), 3650 * 24L * 60L * 60L); x509Certificate [] certificat {certificat}; Try {Savepfx ("RootCa", certificat {certificat}; Try { cak.getPrivateKey(), "123456", certs,"f://RootCa.pfx");} catch (Exception e) {e.printStackTrace();}// 后一个long型参数代表从现在开始的有效期 单位为秒(如果不想从现在开始算 可以在后面改这个域)BASE64Encoder base64 = new BASE64Encoder();FileOutputStream fos = new FileOutputStream(new File("f://RootCa.crt"));// fos.write(certificate.getEncoded());// 生成(保存)cert文件 base64加密 当然也可以不加密base64.encodeBuffer(certificate.getEncoded(), fos);fos.close();}public void signCert() throws NoSuchAlgorithmException,CertificateException, IOException, UncoverableKeyException, InvalidKeyException, NosuchProvideRexception, SignatureException {try {keystore ks = keystore.getInstance ("pkcs12"); fileInputStream ksfis = new FileInputStream ("f: //rootca.pfx"); char [] storepwd = "123456" .tocharArray (); char [] keypwd = "123456" .tocharay (); // 从给定输入流中加载此 keystore。ks.load (ksfis, storepwd); ksfis.close (); // 返回与给定别名关联的密钥 (私钥) , 并用给定密码来恢复它。必须已经通过调用 SetkeyEntry , 或者以 // SeclekeyEntry // 或 SecretkeyenTry 为参数的 SETENTRY 关联密钥与别名。 或者以 或者以 或者以 // SECTIVEENTRY // 或 SecretKeyenTry 为参数的 SetTentry 关联密钥与别名。 关联密钥与别名。 或者以 或者以 或者以 // SeclekeyEntry // 或 SecretkeyentRy 为参数的 SetTentry 关联密钥与别名。 , 或者以 或者以 // SeclekeyEntry // 或 SecretkeyenTry 为参数的 SetTentry 关联密钥与别名。 关联密钥与别名。 或者以 或者以 // SECTIVEENTRY // 或 SecretkeyenTr = (PrivateKey) ks.getkey ("rootca", keypwd); // 返回与给定别名关联的证书。如果给定的别名标识通过调用 setCertificateEntry 创建的条目 , 或者通过调用以 // TrustEdCertificateEntry 为参数的 SetTentry // 创建的条目 , 则返回包含在该条目中的可信证书。如果给定的别名标识通过调用 SetkeyEntry 创建的条目 , 或者通过调用以 // privateKeyEntry 为参数的 Settenry 创建的条目 , 则返回该条目中证书链的第一个元素。x509certificate Certificate = (x509certificate) ks.getCertificate ("rootca"); createCert (Certificate, privk, genkey ());} catch (keystoreException e) {// todo public kepenerated catch blocke.printstackTrace ();}} public keypaRKEY () lance nosuchalgorithMexception {keyPairGenerator kpg = KeyPairGenerator.getInstance ("RSA"); kpg.inialize (1024, sr); System.out.print (kpg.getalgorithm ()); keypair kp = kpg.generatekeypair (); return kp;} public static Void Main (String [] args) {essai {Genx509Cert GCERT = new GenX509Cert (); gcert.createrootca (); gcert.signCert ();} catch (exception e) {// todo généré par Auto-généré Blocke.printStackTrace ();}}}以上这篇纯 Java 实现数字证书生成签名的简单实例就是小编分享给大家的全部内容了 , 希望能给大家一个参考 , 也希望大家多多支持武林网。