IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sécurité Java Discussion :

Cipher et Certificat


Sujet :

Sécurité Java

  1. #1
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut Cipher et Certificat
    Bonjour,

    Alors voilà mon problème, je cherche à vérifier que l'encryption RSA d'une donnée via un certificat s'est bien passée, en la décryptant grâce à la clé public dudit certificat. Essuyant de nombreux échecs j'en suis venu à pondre un petit bout de code qui résume mon problème, le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /***********************************************************/
    String message	= "un message à encrypter";
    String alias	= "FAKE-alias";
    String pass	= "FAKE-pass";
     
    // on load le keystore
    KeyStore ks = KeyStore.getInstance("Windows-MY");
    ks.load(null, null);
     
    // on récupère un certif, sa clé privée et sa clé publique
    X509Certificate certificate	= (X509Certificate)ks.getCertificate(alias);
    PrivateKey	privatekey	= (PrivateKey)ks.getKey(alias, pass.toCharArray());
    PublicKey	publickey	= certificate.getPublicKey();
     
    // on ciphe dans un sens
    Cipher cipherencrypt = Cipher.getInstance("RSA");
    cipherencrypt.init(Cipher.ENCRYPT_MODE, privatekey);
    byte[] encrypted = cipherencrypt.doFinal(message.getBytes());
     
    // on ciphe dans l'autre sens
    Cipher cipherdecrypt = Cipher.getInstance("RSA");
    cipherdecrypt.init(Cipher.DECRYPT_MODE, publickey);
    byte[] decrypted = cipherdecrypt.doFinal(encrypted);
     
    System.out.println(new String(decrypted));
    /***********************************************************/
    Sur le dernier doFinal() j'ai l'exception suivante :
    javax.crypto.BadPaddingException: Data must start with zero
    (je vous passe le reste de la pile)

    * Pour être sûr de pas écrire n'importe quoi j'ai tenté la même manip' avec une paire de clés générées par KeyPairGenerator, et j'obtiens bien la relation : Message = Décrypte(CléPublique, Encrypte(ClePrivée, Message)

    * J'ai également tenté différents Modes et Paddings pour l'instanciation des cipher (ex. : "RSA/ECB/PKCS1Padding")

    Comme vous pouvez le voir je patauge bien comme il faut. Toute aide sera donc la bienvenue, merci d'avance

    PS : j'ai cherché des pistes sur différents forum (notamment celui-ci), mais plus j'en lis plus ça m'embrouille, rien ne fonctionne comme je l'imagine :s

  2. #2
    Expert confirmé
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 419
    Par défaut
    Avec des algo asymétriques on chiffre avec la clef publique et on déchiffre avec la clef privée.

    La clef publique c'est le cadenas qui est à disposition de tout ceux qui veulent envoyer un message chiffré au détenteur du certificat et la clef privée c'est la clef du cadenas qui n'est connue que du détenteur du certificat et du coup lui seul peut déchiffrer.

    Toi tu fais l'inverse.

  3. #3
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Merci pour ta réponse.

    Je vais déjà tenter une batterie de tests via les -trop- nombreuses API de sécu, et je reviendrai certainement vers toi avec d'autres questions sûrement tout aussi bêtes ^^

  4. #4
    Expert confirmé
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 419
    Par défaut
    J'ai oublié le "a" ! C'est corrigé.

    Sinon ton code est correct, il te faut juste inverser l'utilisation des variables privatekey et publickey et ça devrait rouler.

  5. #5
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Re salut,

    Alors tu avais vu juste pour mon problème avec les Cipher, encore merci

    Je vais maintenant t'exposer mon incompréhension :

    Mon objectif final est de faire de la signature électronique (étonné ? ^^).
    Or tout semble indiquer qu'il faille encrypter avec une clé privée, décrypter avec la clé publique.
    C'est ce qu'on retrouve dans les exemples de code, comme dans les textes explicatifs (*).
    De plus j'ai créé moi-même un couple clés publique/privée (via KeyPairGenerator), et l'encryption par clé privée, puis décryption par clé publique, fonctionne bien.
    Ensuite, une signature (preuve) contient le certif (encodé base64), où on peut trouver la clé publique pour la validation ...
    Enfin, rien que par définition, il paraîtrait étrange que ce soit la clé privée qu'on trimbale.

    Je sais, je donne l'impression d'être complétement à l'ouest sur le sujet, mais t'inquiète pas ... c'est pas qu'une apparence ^^

    (*) : j'ai des sources ! c'est pas du vent ! :p

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Tu as raison, dans tous les cas, on ne transmet jamais sa clé privée.
    Dans le cas d'un chiffrage, on chiffre avec la clé publique du destinataire.

    Dans le cas d'une signature, on crée la signature avec sa clé privée, mais on transmet la clé publique dans le document.

  7. #7
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Merci de participer fr1man, plus on est de fous plus on rit :p

    Mais me dire que j'ai raison ne m'aide pas vraiment, au contraire

    S'il faut bien faire Encrypt(data, privateKey) / Decrypt(data, publicKey) dans le cadre d'une signature électronique, comment suis-je censé l'implémenter alors que mes Cipher ne semblent vouloir fonctionner que dans l'autre sens ?

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 277
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Bon ça, c'était la théorie.
    Pour la pratique, je ne suis pas le plus calé dans le domaine.
    Mais bon, à mon avis, tu n'utilises pas les bonnes classes si c'est de la signature que tu cherches à faire.
    Regarde de ce côté là :
    http://download.oracle.com/javase/tu...ign/index.html

  9. #9
    Expert confirmé
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 419
    Par défaut
    Pas mieux que fr1man.

  10. #10
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Oki, je me retape la doc et je reviendrais certainement vers vous
    Merci pour ces réponses en tout cas.

  11. #11
    Membre Expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Par défaut
    Me revoilou,

    ... avec un joli pavé à lire pour vous ^^ (j'ai mis en gras les questions pour qu'elles ressortent).

    J'ai eu le temps de (re)lire la doc que vous m'avez faite suivre.
    J'avais déjà réalisé des essais de code sur les objets de java.security, où tout semble fonctionner correctement.
    Maintenant cela ne fait que mettre en exergue mon incompréhension.
    En effet, comment deux objets censés implémenter le même algo de cryptage peuvent-ils fonctionner différemment ?
    Les deux encrypte/décrypte en RSA, mais le Cipher avec (respectivement) public/privée et la Signature avec privée/public, les inverses ne fonctionnant pas ?
    RSA (Rivest Shamir Adleman) est pourtant un algo, pas une famille d'algo, il n'a qu'une forme ...

    Autre point : j'ai également fait des essais de code avec les objets du package javax.xml.crypto.dsig (pour les signatures DSIG/XAdES).
    J'obtiens bien de jolies signatures, agrémentées de joli XML, pour résumer : la preuve semble correcte.
    Maintenant je ne comprends pas trop comment vérifier cette signature.
    J'ai utilisé javax.xml.crypto.dsig.XMLSignature.Validate(), à travers une fonction légèrement pompée chez libersign :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public boolean verify(byte[] data, byte[] signature) { 
    	javax.xml.parsers.DocumentBuilderFactory documentBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
    	documentBuilderFactory.setNamespaceAware(true);
    	org.w3c.dom.Document signatureDocument = documentBuilderFactory.newDocumentBuilder().parse(new java.io.ByteArrayInputStream(signature));
    	org.w3c.dom.NodeList nodeList = signatureDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    	if (nodeList.getLength() == 0) {
    		throw new javax.xml.crypto.dsig.XMLSignatureException("L'élément Signature est manquant.");
    	}
    	XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
    	DOMValidateContext validateContext = new DOMValidateContext(new PublicKeySelector(), nodeList.item(0));
    	ContextSpecificURIDereferencer uriDereferencer = new ContextSpecificURIDereferencer(signatureFactory.getURIDereferencer());
     
    	uriDereferencer.setData(data);
    	validateContext.setURIDereferencer(uriDereferencer);
    	javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(validateContext);
     
    	return xmlSignature.validate(validateContext);
    }
    - Si j'appelle cette fonction avec une "data" différente de celle qui a servi à monter "signature", la fonction me renvoie quand même true :s
    - Si j'accède au la SignatureValue (SHA1withRSA des data) j'arrive bien à décrypter via Cipher ET avec ma clé publique (hein ? quoi ?). Toutefois le résultat ne correspond absolument pas au SHA1 des data originales.
    Difficile de tourner ça sous forme de question, je m'en tiendrai à : Oh ! Mais qu'est-ce que quoi !? ou bien ?

    Merci d'avoir pris le temps de me lire

Discussions similaires

  1. [JWS] Pb de certificat avec Bouncy Castle
    Par elitost dans le forum JWS
    Réponses: 5
    Dernier message: 20/10/2009, 12h11
  2. Certificat SSL ...
    Par rgarnier dans le forum XMLRAD
    Réponses: 12
    Dernier message: 22/03/2005, 10h11
  3. Forms6i - JavaBean/PJC - Probleme de certificat
    Par patmaba dans le forum Forms
    Réponses: 3
    Dernier message: 13/01/2005, 17h51
  4. Certificats et HTTPS
    Par jean.lamy dans le forum Sécurité
    Réponses: 3
    Dernier message: 24/06/2004, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo