Oppure

Loading
05/05/10 11:01
lespeol

Scusate la vaghità del topic ma il problema è vasto e non riesco a venirne a capo.

Devo fare un programma in java che crei chiave privata e chiave pubblica (RSA).

La pubblica devo poterla inserire in un keystore E devo poterla usare in un certificato x509 da usare però in formato p12. Perché mi serve sia lato server per riconoscere la firma con la chiave privata (quindi la tengo in un keystore) e sia lato client per poter accedere a un sito "sicuro" (p12).

Ho letto molto ma non trovo quello che cerco.

Spero mi possiate aiutare.

Grazie in anticipo :k:
aaa
15/05/10 11:03
lespeol
Risolto... ma sembra che non importi a nessuno.

Fa nulla :k:
aaa
15/05/10 12:12
netarrow
quando si giunge a una soluzione senza che qualcuno ti abbia risposto è buona norma condividerla.
aaa
15/05/10 12:20
lespeol
Sì sì... appena metto tutto insieme posto.
aaa
16/05/10 11:13
lespeol
Allora:

questa classe serve per creare un certificato pkcs12 partendo dal certificato della CA:

X509CertificateGenerator.java

public class X509CertificateGenerator {
	
	private X509Certificate caCert;
    private RSAPrivateCrtKeyParameters caPrivateKey;
	
	
    public X509CertificateGenerator()
	throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, InvalidKeyException, NoSuchProviderException, SignatureException {
		
        String caFile = "my-ca.p12";
        String caPassword = "password";
        String caAlias = "super-CA"; // io ho messo queto alias
		
        KeyStore caKs = KeyStore.getInstance("PKCS12");
		
        caKs.load(new FileInputStream(new File(caFile)), caPassword.toCharArray());
		
        // carica la chiave dal keystore
        Key key = caKs.getKey(caAlias, caPassword.toCharArray());
        if (key == null) {
            throw new RuntimeException("Got null key from keystore!");
        }
        RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) key;
        caPrivateKey = new RSAPrivateCrtKeyParameters(privKey.getModulus(), privKey.getPublicExponent(), privKey.getPrivateExponent(),
													  privKey.getPrimeP(), privKey.getPrimeQ(), privKey.getPrimeExponentP(), privKey.getPrimeExponentQ(), privKey.getCrtCoefficient());
        // poi prendo il certificato
        caCert = (X509Certificate) caKs.getCertificate(caAlias);
        if (caCert == null) {
            throw new RuntimeException("Got null cert from keystore!");
        }
        caCert.verify(caCert.getPublicKey());
    }
	
    public boolean createCertificate(String dn, String reparto, int validityDays, String exportFile, String exportPassword) throws
	IOException, InvalidKeyException, SecurityException, SignatureException, NoSuchAlgorithmException, DataLengthException, CryptoException, KeyStoreException, NoSuchProviderException, CertificateException, InvalidKeySpecException {
        SecureRandom sr = new SecureRandom();
		
        PublicKey pubKey;
        PrivateKey privKey;

		// genero le chiavi
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024, sr);
        KeyPair keypair = keyGen.generateKeyPair();
        privKey = keypair.getPrivate();
        pubKey = keypair.getPublic();
        
        Calendar expiry = Calendar.getInstance();
        expiry.add(Calendar.DAY_OF_YEAR, validityDays);
		
        ////////////////////////////////////////
        /// Qui vanno i dati del certificato ///
        ////////////////////////////////////////
        X509Name x509Name = new X509Name("CN="+dn+", OU=ASL-Medico, O="+reparto+", L=perugia, ST=italia, C=it");
		
        V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator();
        certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis())));
        certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert));
        certGen.setSubject(x509Name);
		
        DERObjectIdentifier sigOID = X509Util.getAlgorithmOID("SHA1WithRSAEncryption");
        AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull());
        certGen.setSignature(sigAlgId);
        certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pubKey.getEncoded())).readObject()));
        certGen.setStartDate(new Time(new Date(System.currentTimeMillis())));
        certGen.setEndDate(new Time(expiry.getTime()));
		
        // attenzione: SHA1+RSA!
        SHA1Digest digester = new SHA1Digest();
        AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine());
        TBSCertificateStructure tbsCert = certGen.generateTBSCertificate();
		
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        DEROutputStream dOut = new DEROutputStream(bOut);
        dOut.writeObject(tbsCert);
		
        // firmiamo
        byte[] signature;
		
		
        // tramite JCE
        PrivateKey caPrivKey = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateCrtKeySpec(caPrivateKey.getModulus(), caPrivateKey.getPublicExponent(),
																									  caPrivateKey.getExponent(), caPrivateKey.getP(), caPrivateKey.getQ(),
																									  caPrivateKey.getDP(), caPrivateKey.getDQ(), caPrivateKey.getQInv()));
		
        Signature sig = Signature.getInstance(sigOID.getId());
        sig.initSign(caPrivKey, sr);
        sig.update(bOut.toByteArray());
        signature = sig.sign();
		
        // qui creiamo il certificato
        ASN1EncodableVector v = new ASN1EncodableVector();
		
        v.add(tbsCert);
        v.add(sigAlgId);
        v.add(new DERBitString(signature));
		
        X509CertificateObject clientCert = new X509CertificateObject(new X509CertificateStructure(new DERSequence(v)));
        clientCert.verify(caCert.getPublicKey());
		
        // esportiamo come PKCS12
		
        PKCS12BagAttributeCarrier bagCert = clientCert;
        bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName,new DERBMPString("Certificate for IPSec WLAN access"));
        bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId,new SubjectKeyIdentifierStructure(pubKey));
		
        KeyStore store = KeyStore.getInstance("PKCS12");
		
        store.load(null, null);
		
        X509Certificate[] chain = new X509Certificate[2];
        // prima il client, poi la CA
        chain[0] = clientCert;
        chain[1] = caCert;
		
        store.setKeyEntry("", privKey, exportPassword.toCharArray(), chain);
		
        FileOutputStream fOut = new FileOutputStream(exportFile);
		
        store.store(fOut, exportPassword.toCharArray());
		
        return true;
    }
	
}


Spero sia chiaro... gli "import" sono tantissimi. Cmq ho usato le librerie di bouncycastle.


Mentre per inserire le chiavi in un keystore patendo da un file PKCS12 ho fatto così:

kStoreCliente.java

public class kStoreCliente {
	
    private String caAlias;
    private String caPassword;
    private String caFile;
    private String aliasIn;
    private String storeFile;
    private String keyStorePass;
	
    public kStoreCliente(String pass, String fileClienteCert) {
		
        caPassword = pass; //canestro
        caFile = fileClienteCert; //caFile = "my-ca.p12";
		aliasIn = "cliente";
        storeFile = "my-store.keystore";
        keyStorePass = "storepass";
        caAlias = ""; // l'ho lasciato vuoto per comodità
	}
	
    public void creaKStore() {
        try {
			
            //Load del file my-ca.p12
            KeyStore caKs = KeyStore.getInstance("PKCS12");
            caKs.load(new FileInputStream(new File(caFile)), caPassword.toCharArray());
			
			
            //Test sull'esistenza del keystore
            if (new File(storeFile).exists()) {
				
				
                //Se il keystore esiste effettuo il load
                System.out.println("Ho trovato keystore - file: " + storeFile);
                KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
                FileInputStream in = new FileInputStream(storeFile);
                ks.load(in, keyStorePass.toCharArray());
                in.close();
				
                try {
					
                    // Estraggo il certificato relativo all'alias CA (aliasIN - vedi dopo)
                    java.security.cert.Certificate cert = ks.getCertificate(aliasIn);
					
                    if (cert != null) {
						
                        System.out.println("Trovato certificato di " + aliasIn + " nel keystore - file: " + storeFile);
                        PublicKey publicKey = cert.getPublicKey();
						
                    } else {
						
                        System.out.println("Non ho trovato certificato di " + aliasIn + " nel keystore - file: " + storeFile);
                    }
					
                } //catch (UnrecoverableKeyException e) { System.out.println(e.toString());}
                //catch (NoSuchAlgorithmException e) { System.out.println(e.toString()); }
                catch (KeyStoreException e) {
                    System.out.println(e.toString());
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
				
            } else {
				
                //Se il keystore non esiste creo un nuovo keystore
                System.out.println("Non ho trovato keystore - file: " + storeFile);
                KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
                ks.load(null, null);
				
                try {
					
                    // Get private key
                    Key key = caKs.getKey(caAlias, caPassword.toCharArray());
					
                    if (key instanceof PrivateKey) {
                        // Get certificate of public key
                        java.security.cert.Certificate cert = caKs.getCertificate(caAlias);
                        // Get public key
                        PublicKey publicKey = cert.getPublicKey();
                        // Return a key pair
                        KeyPair keys = new KeyPair(publicKey, (PrivateKey) key);
						
                        //inserisco il certificato di my-ca dal file .p12 nel keystore appena creato
                        //con alias CA
                        ks.setCertificateEntry(aliasIn, cert);
						
                    }
					
                } catch (UnrecoverableKeyException e) {
                    System.out.println(e.toString());
                } catch (NoSuchAlgorithmException e) {
                    System.out.println(e.toString());
                } catch (KeyStoreException e) {
                    System.out.println(e.toString());
                } catch (Exception e) {
                    System.out.println(e.toString());
                }
				
                FileOutputStream out = new FileOutputStream(storeFile);
				
                //Salvo il keystore su file con password
                ks.store(out, keyStorePass.toCharArray());
                out.close();
                System.out.println("Creato keystore - file: " + storeFile);
                JOptionPane.showMessageDialog(null, "KeyStore creato con successo", "Successo", JOptionPane.INFORMATION_MESSAGE);
            }
			
        } catch (Exception e) {
            System.out.println(e.toString());
        }
		return;
    }
}


Spero che queste semplici classi possano essere utili. Per me lo sono state.

PS: è codice grezzo non ci sono grossi controlli. Ma funziona.
Ultima modifica effettuata da lespeol 16/05/10 11:15
aaa