Source: http://www.mayrhofer.eu.org/create-x509-certs-in-java
Nire probem adierazpena zen erraza da: eremu gutxi batzuk besterik ari konfiguragarriak ziurtagiria X.509 bat sortu,, CA lehendik gako pribatua / ziurtagiria konbinazio sinatu, eta, PKCS12 formatu ziurtagiri berria idazteko. Ondoren, konplikatuak izan zen: behar dut Java, PDA bat.
2 egun eman nituen itxuraz erraza hori lortzeko lan egiteko, eta beraz, pentsatu nuen nire aurkikuntza onak partekatzeko itxaropena beste batzuk izango dira antzeko arazoak izan daiteke.
Ez dira asko, komando-lerroko tresnak eskuragarri X.509 ziurtagiriak, Sun JDK edo openssl banatzen keytool bezala, askotan plataforma anitza sortzeko. Beraz, zergatik Java klase bat egiten hassle bidez joan? Jotzen dut garrantzitsutzat jotzen heldua eta frogatutako openssl toolkit erabiliz eta, besterik gabe deituzRuntime.Exec, egokia parametroak eta sarrera estandarra igarotzean. Hala ere, hau dakar dagozkio plataformak ez J2SE, J2ME PDA JVMs (sarritan CDC) edo baita telefono mugikorra (sarritan CLDC) bezalako arazo larriak. Sistemaren komandoak exekutatzen batzuetan CDC onartuta, baina ia inoiz ez CLDC batera.Gainera, openssl config fitxategia ezin izan behar du
Horrela, openssl egonkorra da eta Desktop-itxurako plataforma (J2SE) lan egiten du, batez ere, plataforma gehiago kapsulatutako da erronka. Sagarra ziztadak eta saiatu sorrera zuzenean Java ziurtagiria ezartzeko erabaki nuen.
Kripto edozein lan egiten duten Java aukeratu J2SE bertsio berriago gehiago sartzen JCE-/ JSSE-azpiegitura begi-bistakoa da. JCE da, arrazoi historikoak eta gaur egun zaharkituta egongo dira (oso hautsita) AEBetako esportazio lege, azpiegitura eta hornitzailearen zatiak, non J2SE hasi lehenetsia SunJCE hornitzailean bidalketa version 1.4 zatitzen direla. Baina, antzeko egoera Runtime.Exec, JCE da apenas erabilera kapsulatutako targetted JREs onartzen, beraz, ez dezakegu bere gain hartzen PDAk edo telefono mugikorrak eskuragarri izango da. Gaietan okerragoa egiteko, JCE ez da hirugarrenen liburutegiak replaceable jada, eta beraz, ia posible da JCE liburutegiak ontziratu aplikazioa.
Java-rekin, kripto eragiketak alternatiba bat bikaina liburutegia Bouncycastle da. JCE hornitzailearen gisa jardun ahal izango da, baina ere bere kripto eta erabilgarritasun-errutinen JCE azpiegitura erabili daiteke modu independentean from API "arina". Bouncycastle from eskolak eskuragarri daude oso lizentziapean liberal eta edozein aplikazio gehitu daiteke eta, beraz, kripto plataformak ez dutela beren JRE laguntza eskainiz. API Bouncycastle arin (Hemendik aipatzen BC bezala) belaunaldi ziurtagiria ezartzea erabaki nuen.
Oharra: Tamalez, org.bouncycastle.x509.X509Util klasea ez da markatu publikoa, Bouncycastle JAR eta beraz, ez dira ouside erabiltzen. Kodea honako lan egin behar da, publiko egin ahal izateko, normalean source eraldatzeko, eta JAR da berriz-sortzeko. Para OpenUAT toolkit, klaseak Bouncycastle azpimultzo bat kopiatu nuen iturburu zuhaitza (pakete ez aldatu, nahiz eta), horiek aldatzeko, nahikoa, J2ME azpian lan egin eta espazioa aurrezteko mendekotasunak minimizatu ahal izateko. Aukera bat da, beraz,, source lortzeko azken OpenUAT eta sartutako eskolak Bouncycastle: erabili. Beste iturburu Bouncycastle azken deskargatu da eta beharrezko aldaketak egiteko.
Ziurtagiria gako berriak bikote bat sortzea oso erraza da nahiko zuzen-bai JCE eta K. a. Aurrera:
KeyPairGenerator Keygen = KeyPairGenerator.getInstance (& quot; RSA ");
keyGen.initialize (1024, sr);
Gako pare gako pare = keyGen.generateKeyPair ();
privKey = keypair.getPrivate ();
pubKey = keypair.getPublic ();
JCE erabiliz gako parea sortzen da, bitartean
RSAKeyPairGenerator gen = new RSAKeyPairGenerator ();
gen.init (new RSAKeyGenerationParameters (, Big Integer.valueOf (3), sr, 1024, 80));
AsymmetricCipherKeyPair gako pare = gen.generateKeyPair ();
RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic. ();
RSAPrivateCrtKeyParameters privateKey = Herria (RSAPrivateCrtKeyParameters) keypair.getPrivate ();
/ / Ziurtagiria kodeketa egokia lortzeko erabiltzen
RSAPublicKeyStructure pkStruct = berria RSAPublicKeyStructure-(publicKe y.getModulus (), publicKey.getExponent ());
/ / JCE formatuan ziurtagiria beharrezko getEncoded delako () beharrezkoa da...
pubKey = KeyFactory.getInstance ("R SA"). generatePublic (
berri RSAPublicKeySpec (publicKey.get Moduloen (), publicKey.getExponent. ()));
/ / Eta hau KeyStore da
privKey = KeyFactory.getInstance ("R SA"). generatePrivate (
, berriak RSAPrivateCrtKeySpec (publicKey. getModulus (), publicKey.getExponent (),
privateKey.getExponent (), privateKey.getP. (), privateKey.getQ. (),
privateKey.getDP (), privateKey.getDQ (), privateKey.getQInv ()));
, BC batekin egiten da. Mesedez, ohartu, une honetan, beste kodeak dago gakoa ordezkaritza BC bihurtzeko JCE ordezkaritza ziurtagiri egitura sortu eta, PKCS12 sartu inportatu aurretik. Bi gai horiek konpontzeko JCE laster laguntzarik gabe eta, beraz, bihurketa lerroak kentzeko espero dut.
Orain, eskuragarri gako publiko berri izatea, bat X.509 ziurtagiri berriaren egitura daitezke jarri. BC benetan X509v3CertificateGenerator utilitate Eginkizun honetan klase ematen du, baina handia oinarritzen JCE azpiegitura. Beraz, bere kodea batzuk dut bikoiztuz, baina soilik K. a. API erabiltzen ahal den neurrian eta, beraz, mendekotasunak kendu JCE klaseak.
Egutegia iraungitze = Calendar.getInstance ();
expiry.add (Calendar.DAY_OF_YEA R, validityDays);
X509Name x509Name = new X509Name ("CN ="+ dn);
V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator ();
certGen.setSerialNumber ("berria DERInteger (BigInteger.valueOf (System.currentTimeMillis ())));
certGen.setIssuer Herria (PrincipalUti l.getSubjectX509Principal Euskal Herria (caCe RT));
certGen.setSubject (x509Name);
DERObjectIdentifier sigOID = X509Util.getAlgorithmOID ("; SHA1WithRSAEncryption:");
AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier (sigOID, DERNull berria ());
certGen.setSignature (sigAlgId);
certGen.setSubjectPublicKeyInf o (berria SubjectPublicKeyInfo ((ASN1Sequ Encia) ASN1InputStream berria (
berri ByteArrayInputStream (pubKey.ge tEncoded ())) readObject ()));
certGen.setStartDate (berria Time (new Date (System.currentTimeMillis ())));
certGen.setEndDate (Time (expiry.getTime ()));
Da; TBSCertificateStructure tbsCert = certGen.generateTBSCertificate ();
Kodea snippet hau, baizik eta delikatua bit batzuk daude:
certGen.setSubjectPublicKeyInf o ("berria SubjectPublicKeyInfo (sigAlgId, pkStruct.toASN1Object ()));
baina hau izan zen openssl by irakurtezinak. Oraindik daukat, bakarrik gako publikoa klase JCE bertsioa getEncoded () metodoa zergatik kodeketa zuzena sortzen du, edo, modu ezberdinean phrased, zer da kodeketa zuzena jakiteko.
Osoa CA, bere auto-sinatutako ziurtagiria eta gako pribatua elkartuak osatzen dute, to jasotako PKCS12 fitxategi batean egingo suposatuko dugu. Karga daitezke klase JCE KeyStore erabiliz:
KeyStore caKs = KeyStore.getInstance ("PKC S12");
caKs.load (new FileInputStream (berri-Artxiboaren (caFile)), caPassword.toCharArray ());
/ / Kargatu sarreraren giltza keystore hasita
Key key = caKs.getKey (caAlias, caPassword.toCharArray ());
(gako == null) {
bota berri RuntimeException (", Got null gakoa keystore!");
}
RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) gakoa;
caPrivateKey = new RSAPrivateCrtKeyParameters (pri vKey.getModulus (), privKey.getPublicExponent (), privKey.getPrivateExponent. (),
privKey.getPrimeP (), privKey.getPrimeQ. (), privKey.getPrimeExponentP. (), privKey.getPrimeExponentQ (), privKey.getCrtCoefficient ());
/ / Eta ziurtagiria jaso
caCert = (X509Certificate) caKs.getCertificate (caAlias);
(caCert == null) {
bota berri RuntimeException ("Got null CERT keystore!");
}
caCert.verify (caCert.getPublic Key ());
Oraindik JCE eskolak erabiliz egin gabe, modu bat aurkitu behar dut.
, CA gakoa ziurtagiria egitura sortu sinatzea ere aktibatuta harrigarriro zaila izango dela Parte bloke kodeketa:
SHA1Digest digestor = new SHA1Digest ();
AsymmetricBlockCipher RSA = new PKCS1Encoding (new RSAEngine ());
ByteArrayOutputStream & nb sp; bOut = new ByteArrayOutputStream ();
DEROutputStream & nb sp; & nb sp; dOut = new DEROutputStream (bOut);
dOut.writeObject (tbsCert);
-byte [] sinadura;
byte [] certBlock-= bOut.toByteArray ();
/ / Lehen sortu digest
digester.update (certBlock, 0, certBlock.length.);
byte [] hash = berria byte [digester.getDigestSize ()];
digester.doFinal (hash, 0);
/ / Eta Egileari galderarik egin nahi badiozu edo iradokizunik utzi nahi baduzu, lehenengo saioa hasi behar dela
rsa.init (true, caPrivateKey);
DigestInfo dInfo = new DigestInfo (berri AlgorithmIdentifier (X509Object Identifiers.id_SHA1, null), hash);
byte [] digest = dInfo.getEncoded (ASN1Encodable DER.);
Sinadura = rsa.processBlock (digest, 0, digest.length.);
v.add (tbsCert);
v.add (sigAlgId);
v.add ("berria DERBitString (sinadura));
Ikus daitekeen bezala,, SHA1 eta RSA erabilera oso zaila da-kodetuak ziurtagiria definitutako sinadura id bat Bloke honetan. Delikatua piezak hemen daude, RSA sinadura kodeketa eta PKCS1 ASN1 DER bilduma kodeketa erabili sinatu aurretik. BC JCE hornitzailearen ezartzeko arduraduna kodea irakurri ondoren, erraza da, baina hori gabe....
Azken urratsa, memoria Java objektuak behar fitxategi batean idatzi behar da, horrela, beste makina edo, besterik gabe, hainbat software-pakete bihurtzen inportatu daiteke.
X509CertificateObject clientCert = new X509CertificateObject (berri X509CertificateStructure (DERSequence berria (v)));
clientCert.verify (caCert.getPu blicKey ());
PKCS12BagAttributeCarrier bagCert = clientCert;
bagCert.setBagAttribute (PKCSOb jectIdentifiers.pkcs_9_at_frie ndlyName
berri DERBMPString ("Nire ziurtagiria berriaren izena frindly"));
bagCert.setBagAttribute (
PKCSObjectIdentifiers.pkcs_9_a t_localKeyId
berri SubjectKeyIdentifierStructure Herria (pubKey));
KeyStore store = KeyStore.getInstance ("PKC S12");
store.load (null, null);
X509Certificate [] kate = new X509Certificate [2];
/ / Lehen bezeroa, eta, ondoren, CA ziurtagiria
-katearen [0] = clientCert;
kate [1] = caCert;
store.setKeyEntry (privKey, exportPassword.toCharArray ("gako berri pribatua Nire lagunarteko izena"), kate);
FileOutputStream fOut = new FileOutputStream (exportFile);
store.store (fOut, exportPassword.toCharArray ());
Kodea snippet honek berriro ugari kodea JCE uneko bere garapenean oinarritzen da, eta hori ordezkatzeko modu bat aurkitu behar dut. Ez da zaila dirudi, soilik harrapatzen da, atributua ezartzeko localKeyId horrela inportatzean kodea ziurtagiria eta gako pribatua elkarri lotzeko daiteke.
Inor ez daki nola irakurtzen eta idazten PKCS12 fitxategi erabiliz JCE kodea eta nola BC ziurtagiria, gako publikoa behar bezala kodetu gabe egonez gero, jaregin me line bat mesedez.
Java klase osoa X.509 ziurtagiriak sortzeko ezartzeko aurki daitezke hemen . Bai JCE eta K. a metodoak inplementatzen ditu, JCE hornitzaileak dira askotan azkarragoa delako K. a baino kode bertako erabilera dela eta. GPL ohiko arau guztiak aplikatu dira, eta zalantzarik gabe Eskertuko nuke jakin luzapenak, edozein hobekuntza edo akatsen konponketak, eta beraz, nire ezartzeko eguneratu ahal izango dut, norbaiti egiten du lan nire dizute bada.