2017-03-10 4 views
-1

J'essaie d'utiliser OpenSSL pour générer un certificat que je peux finalement utiliser pour instancier un nouveau X509EncodedKeySpec sans le faire exploser avec InvalidKeySpecException.Comment générer un certificat X509 acceptable pour le constructeur de X509EncodedKeySpec?

Jusqu'à présent, j'ai essayé ce qui suit:

a créé le keypair en utilisant OpenSSL:

openssl req -x509 -newkey rsa:4096 -keyout privkey.pem cert.pem -days 365 

puis dans mon Android classe de cryptage de l'application:

/** @param rawCert is the content of cert.pem, read into a String. */ 
public static PublicKey regenerateKey(String rawCert) 
     throws NoSuchAlgorithmException, InvalidKeySpecException { 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    byte[] certBytes = Base64.decode(rawCert, 0)); 
    return kf.generatePublic(new X509EncodedKeySpec(certBytes)); 
} 

Le Cert lui-même semble comme ceci:

-----BEGIN CERTIFICATE----- 
MIIGDTCCA/WgAwIBAgIJANIT8Fk2cT0HMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD 
(... removed to save space in posting ...) 
Fk7oUsABk7xlpP7kS5+lKfLk+/6DvwIyjU8PB6faBe8EDgXSZMh9K/36Onpvr62i 
ysBiCKTT+y+NC3u4cFiTjR4= 
-----END CERTIFICATE----- 

Pour ce que ça vaut, je l'ai déjà essayé les expériences suivantes:

  • lire le fichier .pem original dans une chaîne (BEGIN/END CERTIFICATE et tout), puis converti en octet [] avec les getBytes de la chaîne (StandardCharsets.UTF_8) méthode. Échoué. Même expérience, mais a plutôt essayé US_ASCII et ISO_8859_1. Toujours échoué.

  • Suppression de la première et de la dernière ligne (le fichier ne contenait donc que le contenu CERT codé en base64). Échoué.

  • Double-vérifié pour vous assurer que le fichier .pem ne s'est pas terminé avec un saut de ligne. Échoué. Base64-décodé le fichier en byte [] au lieu des tentatives antérieures d'utilisation du fichier encodé en base64. Échoué.

la ligne correspondante spécifique à partir de la trace de pile semble être:

java.lang.RuntimeException: java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error: 0c0890ba: ASN.1 routines de codage: asn1_check_tlen: WRONG_TAG

À ce stade, je ne suis pas sûr si le problème est avec le cert lui-même, ou s'il y a quelque chose d'autre (ou à la place) je dois faire pour le masser dans une forme acceptable pour X509EncodedKeySpec.

+0

Cela n'a pas de sens. Un certificat n'est pas une clé publique. Il * contient * une clé publique. Vous devez générer le certificat lui-même, et vous pouvez obtenir la clé publique directement à partir de cela. – EJP

Répondre

1

Vous utilisez la mauvaise méthode. Comme le souligne @EJP le certificat contient une clé publique

CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
Certificate cert = cf.generateCertificate(inputStream); 
PublicKey publicKey = cert.getPublicKey(); 

generateCertificate() accepte un certificat au format PEM (base64 avec en-tête et pied de page) et binaire (suppression en-tête/pied de page et le décodage du contenu base64)

Voir documentation

In the case of a certificate factory for X.509 certificates, the certificate provided in inStream must be DER-encoded and may be supplied in binary or printable (Base64) encoding. If the certificate is provided in Base64 encoding, it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at the end by -----END CERTIFICATE-----.