Paket com.ylsoft.cert; impor java.io.file; import java.io.fileInputStream; impor java.io.fileoutputStream; impor java.io.ioException; impor java.security.invalidkeyException; impor java.security java.security.keystore; impor java.security.keystoreexception; impor java.security.nosuchalgorithmException; impor java.security.nosuchproviderexception; impor java.security.privateKey; impor java.security java.security.signatureException; impor java.security.unrecoverableKeyException; impor java.security.cert.certificate; impor java.security.cert.certificateException; impor java.security.cert.cert.x509certtificate; sun.misc.base64encoder; impor sun.security.util.objectIdentifier; impor sun.security.x509.algorithmid; impor sun.security.x509.certandkeygen; impor sun.security.x509.certificiCiCyTiThmid; impor sun.security.x509.x50.certificiCiCeTiCiTiCiTiChMID; impor sun.security.x50.x50 sun.security.x509.certificateSerialnumber; impor sun.security.x509.certificateValidity; impor sun.security.x509.certificateVersion; impor sun.security.x509.certificatex509key; impor sun.security.x50.extendedKurity; sun.security.x509.KeyIdentifier;import sun.security.x509.KeyUsageExtension;import sun.security.x509.SubjectKeyIdentifierExtension;import sun.security.x509.X500Name;import sun.security.x509.X500Signer;import sun.security.x509.X509CertImpl;import sun.security.x509.x509certinfo;/** * 首先生成 ca 的根证书 , 然后有 然后有 ca 的根证书签署生成 scriptx 的证书 * * @Author Administrator * */kelas publik Genx509cert {/** 提供强加密随机数生成器 (rng) */private Securerandom sr; public genx509cert () throws {nosucccepcepte (nosucccepcepte (noScepcepcepte () nosuchovon, nosuchovon, nosuchovon, nosuchovon, nosuchov () nosuchov () nosuchov () nosuchov () 返回实现指定随机数生成器 (RNG) 算法的 SecureRandom 对象。sr = SecureRandom.getInstance("SHA1PRNG", "SUN");}public void createCert(X509Certificate certificate, PrivateKey rootPrivKey,KeyPair kp) throws CertificateException, IOException,InvalidKeyException, NosuchalgorithMexception, NosuchProviderException, SignatureException {// x.509 v1 证书的抽象类。此类提供了一种访问 x.509 v1 证书所有属性的标准方式。byte certbytes [] = Certificate.getencoded (); // Kelas X509CertImpl mewakili an x.509 Certificate.x509 X509CertImpl (Certbytes); // Kelas X509CertInfo mewakili informasi sertifikat X.509.x509CertInfo x509certinfo = (x509certinfo) x509certImpl.get ("x509.info"); // Kelas ini menentukan X509, "x509.info"); // Kelas ini menentukan X509, "x509.info"); // Kelas ini menentukan X509, "X509.info"); // Kelas ini menentukan X509, "X509.info"); // Kelas ini menentukan X509 ("X509.info"); // Kelas ini menentukan X509 ("X509.info"); // Kelas ini menentukan X509 ("x50999.info"); // Kelas ini menentukan X50999999 new CertificateX509Key(kp.getPublic()));// This class defines the Extensions attribute for the CertificateCertificateExtensions certificateextensions = new CertificateExtensions();certificateextensions.set("SubjectKeyIdentifier",new SubjectKeyIdentifierExtension((new KeyIdentifier (kp.getPublic ())). GetIdentifier ())); x509certInfo.set ("Extensions", CertificateExtensions); // 设置 Penerbit 域 Penerbit X500Name = X500Name ("cn = rootca, ou = hackwp, o = wp, l = bj, s = bj, c = cn"); x509certInfo.set ("issuer.dname", penerbit); // membangun nama dari string mikal yang diformat secara konvensional, seperti // "cn = dave, ou. (RFC 1779 or RFC// 2253 style).X500Name subject = new X500Name("CN=scriptx, OU=wps, O=wps, L=BJ, ST=BJ, C=CN");x509certinfo.set("subject.dname", subject);// 此 Signature 类用来为应用程序提供数字签名算法功能。返回实现指定签名算法的 Signature 对象。Signature signature = Signature.getInstance ("MD5WithRSA"); // 初始化这个用于签名的对象。如果使用其他参数再次调用此方法 , 此调用的结果将无效。Signature.Initsign (kp.getprivate ()); // Kelas ini memberikan ikatan antara objek tanda tangan dan // namanya X.500 yang ditandatangani, dari rantai sertifikat X.509), yang diperlukan // yang diperlukan dalam banyak kunci publik. penerbit); // Kelas ini mengidentifikasi algoritma, seperti transformasi kriptografi, // yang masing -masing dapat dikaitkan dengan parameter. Sertifikatalgoritmid (algoritmid))); // 开始时间 tanggal bdate = tanggal baru (); // 结束时间 tanggal edate = tanggal baru (); // 天 小时 分 秒 毫秒 edate. Valid. 证书的有效时间 Sertifikatevaliditas CertificateValidity = CertificateValidity baru (Bdate, Edate); x509certinfo.set ("validitas", sertifikatevaliditas); // Kelas ini mendefinisikan atribut SerialNumber untuk sertifikat. "SERIFO." SERIFO. "LITIALNOM." CertificateSerialNumber ((int) (tanggal baru (). GetTime ()/ 1000L))); // 设置序列号域, kelas ini mendefinisikan versi sertifikat X509.certificateVersion CV = CertificateVersion baru (CertificateVersion.v3); x509certInfo.set (x509certinfo.v3); x509certInfo.set (x509certinfo.v3); x509certInfo.set (x509certinfo.v3); x509certInfo.set (x509certinfo.vo); , v2, v3 这几个合法值/** * 以上是证书的基本信息 如果要添加用户扩展信息 则比较麻烦 首先要确定 首先要确定 Versi 必须是 v3 否则不行 然后按照以下步骤 */ObjectIdentifier oid = new ObjectIdentifier (int int [] {2, 5, 29, 15}); // 生成扩展域的 id 数组 第 第 1 位最大 2 第 29 位最大 位最大 位最大 生成扩展域的 生成扩展域的 生成扩展域的 生成扩展域的 生成扩展域的 生成扩展域的 1 (f0) "; byte l = (byte) userdata.length (); // 数据总长 17 位 byte f = 0x04; byte [] bs = byte baru [userdata.length () + 2]; bs [0] = f; bs [1] = l; untuk (int i = 2; i <bs.length; i ++) {bs [i] = (byte) userdata.charat (i - 2);} extension ext = ekstensi baru (oid, true, bs); // 生成一个 ekstensi 对象 参数分别为 参数分别为 参数分别为 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , KEYUSAGEEXTENSION (); KEYUSAGE.SET (KEYUSAGEEXTENSION.DIGITAL_SIGNATURE, TRUE); KEYUSAGE.SET (KEYUSAGEEXTENSION.NON_REPUDIASI, TRUE); KEYUSAGE.SET (KEYUSAGEXENSION.KEY_ENCIPHERMENT, true); keyUsage.set (keyUsageExension.datiFension. ObjectIdentifier(new int[] { 1, 3, 6, 1,5, 5, 7, 3, 3 });Vector<ObjectIdentifier> vkeyOid = new Vector<ObjectIdentifier>();vkeyOid.add(ekeyOid);ExtendedKeyUsageExtension exKeyUsage = new ExtendedKeyUsageExtension(vkeyOid);CertificateExtensions exts = new CertificateExtensions (); exts.set ("KeyUsage", KeyUsage); exts.set ("ExtendedKeyUsage", ExkeyUsage); // 如果有多个 Extension 则都放入 CertificateExtensions 类中 , x509certInfo.set (x509certinfo.extensions, exts); // 设置 设置 设置 设置 设置 设置 , x509 X509CertImpl(x509certinfo);x509certimpl1.sign(rootPrivKey, "MD5WithRSA");// 使用另一个证书的私钥来签名此证书 这里使用 md5散列 用rsa来加密BASE64Encoder base64 = new BASE64Encoder();FileOutputStream fos = new FileOutputStream(new File ("f: //scriptx.crt")); base64.encodeBuffer (x509certImpl1.getEncoded (), fos); coba {sertifikat [] certchain = {x509certImpl1}; savePfx ("scriptx", kp.getprivate (), "12344446," scriptx ", kp.getprivate ()," 123441, "scriptx", kp.getprivate (), " certchain, "f: //scriptx.pfx"); FileInputStream in = FileInputStream baru ("f: //scriptx.pfx"); inputkeystore keystickeystore = keystore.getInstance ("pkcs12"); inputkeystore.Load (in, "123456". inputkeystore.getCertificate ("scriptx"); system.out.print (cert.getPublickey ()); privateKey privk = (privateKey) inputKeyStore.getKey ("scriptx", "123456" .tochararray ()); fileOutputStream privkFos = baru (baru. File ("f: //scriptx.pvk")); privkfos.write (privk.getencoded ()); System.out.print (privk); // base64.encode (key.getEncoded (), privkfos); in.close ();} Catch (Exception e) {// too-Auto-Gener); 生成文件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 privKey, String pwd,Certificate[] certchain, string filePath) melempar pengecualian {// 此类表示密钥和证书的存储设施。// 返回指定类型的 keystore 对象。此方法从首选 penyedia 开始遍历已注册安全提供者列表。返回一个封装 keystorespi // 实现的新 keystore 对象 , 该实现取自第一个支持指定类型的 penyedia outkeyStore outputKeyStore = keystore.getInstance ("pkcs12"); System.out.println ("KEYStore (" pkcs12 "); System.out.println (" KEYStore ("pkcs12"); System.out.println ("KEYStore 类型 idik (" pkcs12 "); KeyStore 。可以给定一个密码来解锁 KeyStore (例如 , 驻留在硬件标记设备上的 keystore )或检验 // KeyStore 数据的完整性。如果没有指定用于完整性检验的密码 , 则不会执行完整性检验。如果要创建空 // KeyStore , 或者不能从流中初始化 keystore , 则传递 null 作为 stream 的参数。注意 , 如果此 keystore // 已经被加载 , 那么它将被重新初始化 , 并再次从给定输入流中加载。 并再次从给定输入流中加载。 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 将给定密钥(已经被保护)分配给给定别名。如果受保护密钥的类型为 则它必须附带证明相应公钥的证书链。如果底层 那么它将被重新初始化 则它必须附带证明相应公钥的证书链。如果底层 那么它将被重新初始化 那么它将被重新初始化 则它必须附带证明相应公钥的证书链。如果底层 则它必须附带证明相应公钥的证书链。如果底层 则它必须附带证明相应公钥的证书链。如果底层 则它必须附带证明相应公钥的证书链。如果底层 那么它将被重新初始化 那么它将被重新初始化 那么它将被重新初始化 那么它将被重新初始化 那么它将被重新初始化 , , , , , , , , , , , , , , , , KeyStore 实现的类型为 // JKS , 则必须根据 PKCS #8 标准中的定义将 Kunci 编码为 // EncryptedPrivateKeyInfo 。如果给定别名已经存在 , 则与别名关联的 KeyStore // 信息将被给定密钥(还可能包括证书链)重写。OutputKeyStore.SetKeyEntrry (Alias, Privkey, pwd.tochararray (), certchain); // KeyStore.prtive Keystore.privateKeyEntry (kp.getprivate (), certchain); // keystore.passwordprotection password = baru // keystore.passwordprotection ("123456" .tochararray (); // outputkeystore.setEntrry ("scriptx", pke, kata sandi);存储到给定输出流 , 并用给定密码保护其完整性。OutputKeyStore.Store (out, pwd.tochararray ()); out.close ();} public void saveJKS (string alias, privateKey privkey, string pwd, sertifikat [] certchain, string filePath) melempar pengecualian {keystore outputkeyStore = = Keystore.getInstance ("jks"); System.out.println (outputKeyStore.getType ()); outputkeystore.load (null, pwd.tochararray ()); outputkeystore.setkeyEntry (alias, privey, pwd.tocharray (), CERTCHAIN); alias, pwd.tocharray (), CERTCHOIN); Keystore.privateKeyEntry (kp.getprivate (), certchain); // keystore.passwordprotection password = baru // keystore.passwordprotection ("123456" .tochararray ()); // outputkeystore.setEntrry ("scriptx", pke, kata sandi); FileOutputStream (FilePath); outputKeyStore.Store (out, pwd.tochararray ()); out.close ();}/** * 颁布根证书 , 自己作为 ca * * @Throws nosuchalgorithmexception * @throws nosuchproviderception * @throwsception @throwsception @throwsception * @throwsception @throwsception * @throwsception * @throwsception * @throwsception * @throwsception * @throwsception * @throwsception * @Throws SignatureException * @Throws UncepeCeCableKeyException */public void createrootca () melempar nosuchalgorithmException, nosuchproviderexception, non -non -neasseption, nosuchproviderexception, non -(因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 (因为不知道确切的 nosuchiLEECEXCECTION,既使用默认的 Penyedia) // menghasilkan sepasang kunci, dan menyediakan akses ke mereka. Nama dari string yang diformat secara konvensional, seperti // "cn = Dave, ou = javasoft, o = microsystems matahari, c = us". (RFC 1779 atau RFC // 2253 Gaya) X500Name Subjek = new X500Name ("cn = rootca, ou = hackwp, o = wp, l = bj, s = bj, c = cn"); // mengembalikan sertifikat X.509v3 yang ditandatangani sendiri untuk kunci publik. Sertifikat // segera valid. Tidak ada ekstensi.// sertifikat seperti itu biasanya digunakan untuk mengidentifikasi "sertifikat // otoritas" (CA). Dengan demikian, mereka tidak akan selalu diterima oleh // pihak lain. Namun, sertifikat tersebut juga berguna saat Anda // sedang melakukan bootstrap infrastruktur keamanan Anda, atau sistem penggalian // prototipe. 自签名的根证书 x509certificate sertifikat = Cak.getSelfcertificate (subjek, tanggal baru (), 3650 * 24L * 60L * 60L); x509certificate [] Certicer (), Certific = {Certify {Certific {Certify {Certify {Certify {Certific {60L * 60L); X509 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 (sertifikat.getEncoded ()); // 生成(保存) cert 文件 base64 加密 当然也可以不加密 basis64.encodeBuffer (sertifikat.getencoded (), fos); fos.close ();} public void stiker ()), fos); fos.close ();} public void tanda tangan publik ()), fos); fos. IOException, UnrecoverableKeyException,InvalidKeyException, NoSuchProviderException, SignatureException {try {KeyStore ks = KeyStore.getInstance("pkcs12");FileInputStream ksfis = new FileInputStream("f://RootCa.pfx");char[] storePwd = "123456".toCharArray();char[] keyPwd = "123456".toCharArray();// 从给定输入流中加载此 KeyStore。ks.load(ksfis, storePwd);ksfis.close();// 返回与给定别名关联的密钥(私钥),并用给定密码来恢复它。必须已经通过调用 setKeyEntry,或者以// PrivateKeyEntry// 或 SecretKeyEntry 为参数的 setEntry 关联密钥与别名。PrivateKey privk = (privateKey) ks.getKey ("rootca", keypwd); // 返回与给定别名关联的证书。如果给定的别名标识通过调用 setCertificateEntry 创建的条目 , 或者通过调用以 // trustedCertificateEntry 为参数的 setentry // 创建的条目 , 则返回包含在该条目中的可信证书。如果给定的别名标识通过调用 setKeyentry 创建的条目 , 或者通过调用以 或者通过调用以 或者通过调用以 或者通过调用以 或者通过调用以 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ks.getCertificate("RootCA");createCert(certificate, privK, genKey());} catch (KeyStoreException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public KeyPair genKey() throws NoSuchAlgorithmException {KeyPairGenerator kpg = Keypairgenerator.getInstance ("rsa"); kpg.initialize (1024, sr); System.out.print (kpg.getalgorithm ()); keypair kp = kpg.generatePairir (); return kp;} public static void main (string [] argseyPair (); pRED GENED.9 public static void Main (string [] arge) {{{public static void main (string [] arge) {{public genx. Genx509cert (); gcert.createrootca (); gcert.signcert ();} catch (exception e) {// TODO AUTO-EMETOLED Catch blocke.printstacktrace ();}}}以上这篇纯 Java 实现数字证书生成签名的简单实例就是小编分享给大家的全部内容了 , 希望能给大家一个参考 , ,