¿Es posible crear sanamente un Certificado X509 en código Java sin utilizar las clases Bouncy Castle X509V * CertificateGenerator?¿Cómo crear un certificado X509 en Java sin BouncyCastle?
Respuesta
La capacidad para firmar certificados no es parte de una biblioteca o extensión estándar de Java.
Gran parte del código que se necesita para hacerlo usted mismo es parte del núcleo. Existen clases para codificar y decodificar nombres X.500, extensiones de certificado X.509, claves públicas para varios algoritmos y, por supuesto, para realizar realmente la firma digital.
Implementar esto usted mismo no es trivial, pero es definitivamente factible — Probablemente pasé 4 o 5 días completos la primera vez que hice un prototipo funcional para la firma de certificados. Fue un ejercicio de aprendizaje fantástico para mí, pero es difícil justificar ese gasto cuando hay bibliotecas utilizables disponibles de forma gratuita.
Todos los componentes básicos para hacer un certificado autofirmado (firma, codificación X509, etc.) están disponibles en JRE. A diferencia de BC, Sun's JCE no proporciona ninguna llamada pública para firmar un certificado. Sin embargo, todas las funciones están disponibles en Keytool. Simplemente puede copiar el código de keytool para hacer esto. El método que necesita copiar es doSelfCert()
.
Desafortunadamente, Keytool usa las clases 'sun. *' Para esto. Entonces esto no funcionará con todos los JRE. Sin embargo, aquí está el [código fuente] (https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/sun/security/tools/KeyTool.java) – Pith
Depende de qué es exactamente lo que quiere hacer (y probablemente su definición de "Sanely"). Como señaló ZZ Coder, puede crear un certificado autofirmado directamente copiando keytool. Pero no creo que pueda crear un objeto de solicitud de certificado PKCS10 con la JCE estándar, que probablemente necesite hacer si desea crear CEE estándar firmadas por CA.
Hm, ¿por qué no? ? Keytool puede convertir un auto firmado en un csr, solo necesita copiar ese código también. – eckes
Sí, pero no con las clases documentadas públicamente. Documenté el proceso in this article.
import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
import java.math.BigInteger;
import java.util.Date;
import java.io.IOException
/**
* Create a self-signed X.509 Certificate
* @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
* @param pair the KeyPair
* @param days how many days from now the Certificate is valid for
* @param algorithm the signing algorithm, eg "SHA1withRSA"
*/
X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
throws GeneralSecurityException, IOException
{
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + days * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert to identify the algorithm that's used.
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
// Update the algorith, and resign.
algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
return cert;
}
Un muy buen consejo. Me salvó de importar la temida (y amada) lib de Bouncycastle. Hincharse! –
¿Hay alguna manera de hacerlo que NO implique llamar a sun.security.x509. *? Dado que, de hecho, no es algo que se supone que debes usar. –
Excelente. Me ahorró mucho trabajo. El código es agradable y limpio. Estoy editando el código para asegurarme de que no desaparezca si el blog se cae. – Suma
import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
import java.math.BigInteger;
import java.security.cert.Certificate;
import java.util.Date;
import java.io.IOException;
public class Example {
/**
* Create a self-signed X.509 Example
*
* @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
* @param pair the KeyPair
* @param days how many days from now the Example is valid for
* @param algorithm the signing algorithm, eg "SHA1withRSA"
*/
public X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
throws GeneralSecurityException, IOException {
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + days * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert to identify the algorithm that's used.
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
// Update the algorith, and resign.
algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
return cert;
}
public static void main (String[] argv) throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Example example = new Example();
String distinguishedName = "CN=Test, L=London, C=GB";
Certificate certificate = example.generateCertificateOriginal(distinguishedName, keyPair, 365, "SHA256withRSA");
System.out.println("it worked!");
}
}
me gustó la respuesta de vbence, pero seguí recibiendo la siguiente excepción:
java.security.cert.CertificateException: Asunto tipo de clase no válida.
Después de muchos intentos de averiguar era una clase de sujeto válida descubrí que X509CerInfo quería una instancia de X500Name.
1 info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
2 info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
3 info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
4 info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
Así líneas 2 3 & necesarios para cambiar a
2 info.set(X509CertInfo.SUBJECT, owner);
3 info.set(X509CertInfo.ISSUER, owner);
- 1. Obtener clave privada del Certificado BouncyCastle X509? C#
- 2. Java X509 Certificado de análisis y validación
- 3. ¿Cómo validar el certificado X509?
- 4. Guardar certificado X509 en un archivo
- 5. Solicitud con certificado X509
- 6. Cómo utilizar makecert para crear un certificado X509 aceptado por la WCF
- 7. Crear mediante programación el certificado X509 utilizando OpenSSL
- 8. Crear certificado x509 con la herramienta openssl/makecert
- 9. ¿Generar certificado X509 desde byte []?
- 10. x509 verificación de certificado en C
- 11. ¿Hay alguna manera de imprimir bastante un certificado X509?
- 12. ¿Es posible generar un certificado X509 programáticamente utilizando solo C#?
- 13. ¿Cómo recuperar/calcular la huella digital de un certificado X509 en Java?
- 14. Tienda de llaves PGP (públicas) en java keystore - Bouncycastle
- 15. Tienda X509 Certificado en la base de datos
- 16. Validar certificados X509 con Java APis
- 17. ¿Escribes el certificado x509 en una cadena con formato PEM en java?
- 18. La validación de certificados X.509 con Java y BouncyCastle
- 19. Crear un certificado OpenSSL en Windows
- 20. Número de serie X509 usando java
- 21. Crear cadena de certificados en BouncyCastle en C#
- 22. Android - convertir cadena de certificado pkcs12 en objeto de certificado x509 para bks keystore
- 23. Cómo definir un propósito particular de un certificado X509 en PHP
- 24. C# ¿Cómo puedo validar una cadena de certificado Root-CA-Cert (x509)?
- 25. x509 C# ejemplos?
- 26. Cómo firmar el token X509 usando WCF
- 27. ¿BouncyCastle tiene un servicio SecureRandom?
- 28. Cómo crear un archivo Zip sin comprimir en Java
- 29. ¿Cómo verifico un certificado SSL en python?
- 30. rsacryptoserviceprovider usando certificados x509 C#
¿Sigue siendo exacta a partir de 2017? – user674669