2015-07-23 1 views
0

Je veux créer une signature numérique avec l'aide de SignatureMethod.HMAC_SHA1, pour que j'ai parlé le programme ci-dessoussignature Création avec HMAC_SHA1 - clé secrète exception attendue

package com.sampel.test; 

import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.crypto.*; 
import javax.xml.crypto.dsig.*; 
import javax.xml.crypto.dom.*; 
import javax.xml.crypto.dsig.dom.DOMSignContext; 
import javax.xml.crypto.dsig.keyinfo.*; 
import javax.xml.crypto.dsig.spec.*; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 
import java.security.*; 
import java.util.Collections; 
import java.util.Formatter; 
import java.util.Iterator; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 
import org.w3c.dom.Document; 

/** 
* This is a simple example of generating an Enveloped XML 
* Signature using the JSR 105 API. The resulting signature will look 
* like (key and signature values will be different): 
* 
* <pre><code> 
*<Envelope xmlns="urn:envelope"> 
* <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
* <SignedInfo> 
*  <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n 
-20010315"/> 
*  <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/> 
*  <Reference URI=""> 
*  <Transforms> 
*   <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> 
*  </Transforms> 
*  <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> 
*  <DigestValue>K8M/lPbKnuMDsO0Uzuj75lQtzQI=<DigestValue> 
*  </Reference> 
* </SignedInfo> 
* <SignatureValue> 
*  DpEylhQoiUKBoKWmYfajXO7LZxiDYgVtUtCNyTgwZgoChzorA2nhkQ== 
* </SignatureValue> 
* <KeyInfo> 
*  <KeyValue> 
*  <DSAKeyValue> 
*   <P> 
*   rFto8uPQM6y34FLPmDh40BLJ1rVrC8VeRquuhPZ6jYNFkQuwxnu/wCvIAMhukPBL 
*   FET8bJf/b2ef+oqxZajEb+88zlZoyG8g/wMfDBHTxz+CnowLahnCCTYBp5kt7G8q 
*   UobJuvjylwj1st7V9Lsu03iXMXtbiriUjFa5gURasN8= 
*   </P> 
*   <Q> 
*   kEjAFpCe4lcUOdwphpzf+tBaUds= 
*   </Q> 
*   <G> 
*   oe14R2OtyKx+s+60O5BRNMOYpIg2TU/f15N3bsDErKOWtKXeNK9FS7dWStreDxo2 
*   SSgOonqAd4FuJ/4uva7GgNL4ULIqY7E+mW5iwJ7n/WTELh98mEocsLXkNh24HcH4 
*   BZfSCTruuzmCyjdV1KSqX/Eux04HfCWYmdxN3SQ/qqw= 
*   </G> 
*   <Y> 
*   pA5NnZvcd574WRXuOA7ZfC/7Lqt4cB0MRLWtHubtJoVOao9ib5ry4rTk0r6ddnOv 
*   AIGKktutzK3ymvKleS3DOrwZQgJ+/BDWDW8kO9R66o6rdjiSobBi/0c2V1+dkqOg 
*   jFmKz395mvCOZGhC7fqAVhHat2EjGPMfgSZyABa7+1k= 
*   </Y> 
*  </DSAKeyValue> 
*  </KeyValue> 
* </KeyInfo> 
* </Signature> 
*</Envelope> 
* </code></pre> 
*/ 
public class xmlDigSig { 

    // 
    // Synopsis: java GenEnveloped [document] [output] 
    // 
    // where "document" is the name of a file containing the XML document 
    // to be signed, and "output" is the name of the file to store the 
    // signed document. The 2nd argument is optional - if not specified, 
    // standard output will be used. 
    // 
    public static void main(String[] args) throws Exception { 

     // Create a DOM XMLSignatureFactory that will be used to generate the 
     // enveloped signature 
     XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 

     // Create a Reference to the enveloped document (in this case we are 
     // signing the whole document, so a URI of "" signifies that) and 
     // also specify the SHA1 digest algorithm and the ENVELOPED Transform. 
     Reference ref = fac.newReference 
      ("#_0", fac.newDigestMethod(DigestMethod.SHA1, null), 
      Collections.singletonList 
       (fac.newTransform 
       (Transform.ENVELOPED, (TransformParameterSpec) null)), 
      null, null); 

     // Create the SignedInfo 
     SignedInfo si = fac.newSignedInfo 
      (fac.newCanonicalizationMethod 
      (CanonicalizationMethod.EXCLUSIVE, 
       (C14NMethodParameterSpec) null), 
      fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), 
      Collections.singletonList(ref)); 

     // Create a DSA KeyPair 
     KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); 
     kpg.initialize(512); 
     KeyPair kp = kpg.generateKeyPair(); 

     // Create a KeyValue containing the DSA PublicKey that was generated 
     KeyInfoFactory kif = fac.getKeyInfoFactory(); 
     KeyValue kv = kif.newKeyValue(kp.getPublic()); 

     // Create a KeyInfo and add the KeyValue to it 
     KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

     // Instantiate the document to be signed 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     Document doc = 
      dbf.newDocumentBuilder().parse(new FileInputStream("C:/sample/timestamp.txt")); 

     // Create a DOMSignContext and specify the DSA PrivateKey and 
     // location of the resulting XMLSignature's parent element 
     DOMSignContext dsc = new DOMSignContext 
      (kp.getPrivate(), doc.getDocumentElement()); 
     // Create the XMLSignature (but don't sign it yet) 
     XMLSignature signature = fac.newXMLSignature(si, ki); 
     // Marshal, generate (and sign) the enveloped signature 
     signature.sign(dsc); 
     System.out.println(ref.getURI()); 
     // output the resulting document 
     OutputStream os; 
     if (args.length > 1) { 
      os = new FileOutputStream(args[1]); 
     } else { 
      os = System.out; 
     } 

     TransformerFactory tf = TransformerFactory.newInstance(); 
     Transformer trans = tf.newTransformer(); 
     trans.transform(new DOMSource(doc), new StreamResult(os)); 

    } 
} 

avec le fichier d'entrée comme (dans l'horodatage. txt)

<u:Timestamp u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
       <u:Created>2015-06-18T17:34:40.325Z</u:Created> 
       <u:Expires>2015-06-18T17:39:40.325Z</u:Expires> 
      </u:Timestamp> 

reçois la sortie avec inférieure à la valeur (car elle fait référence méthode DSA)

<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/> 

mais j'ai besoin d'une valeur avec (avec la méthode HMAC_SHA1)

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/> 

donc je modifié le code avec SignatureMethod.HMAC_SHA1 au lieu de SignatureMethod.DSA_SHA1 alors il a commencé à me donner l'exception ci-dessous et également ne suis pas en mesure de trouver le KeyPairGenerator approprié pour HMAC_SHA1.

Exception in thread "main" javax.xml.crypto.dsig.XMLSignatureException: java.security.InvalidKeyException: Secret key expected 
    at com.ibm.xml.crypto.dsig.dom.SignedInfoImpl.sign(SignedInfoImpl.java:189) 
    at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:162) 
    at com.anthem.kytest.xmlDigSig.main(xmlDigSig.java:134) 
Caused by: java.security.InvalidKeyException: Secret key expected 
    at com.ibm.crypto.provider.HmacSHA1.engineInit(Unknown Source) 
    at javax.crypto.Mac.a(Unknown Source) 
    at javax.crypto.Mac.init(Unknown Source) 
    at com.ibm.xml.crypto.dsig.SignatureEngineHMAC.initSign(SignatureEngineHMAC.java:102) 
    at com.ibm.xml.crypto.dsig.dom.SignedInfoImpl.sign(SignedInfoImpl.java:168) 
    ... 2 more 
java.security.InvalidKeyException: Secret key expected 
    at com.ibm.crypto.provider.HmacSHA1.engineInit(Unknown Source) 
    at javax.crypto.Mac.a(Unknown Source) 
    at javax.crypto.Mac.init(Unknown Source) 
    at com.ibm.xml.crypto.dsig.SignatureEngineHMAC.initSign(SignatureEngineHMAC.java:102) 
    at com.ibm.xml.crypto.dsig.dom.SignedInfoImpl.sign(SignedInfoImpl.java:168) 
    at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:162) 
    at com.anthem.kytest.xmlDigSig.main(xmlDigSig.java:134) 

Comment créer une méthode de signature avec HMAC_SHA1, est-il tutoriel/exemple disponible.

Environnement RSA/7 avec ÉTAIT à 1,6 jdk

S'il vous plaît aidez-moi à ce sujet, Merci.

Répondre

0

Vous devez générer une clé secrète symétrique pour HMAC, et non une paire de clés. Les paires de clés sont intrinsèquement pour la cryptographie asymétrique comme RSA et DSA.

Donc, essayez de remplacer la génération de clés de paire avec une génération d'une clé HMAC:

byte[] randomKey = new byte[20]; 
SecureRandom rng = new SecureRandom(); 
rng.nextBytes(randomKey); 
SecretKey hmacKey = new SecretKeySpec(randomKey, "HMAC"); 

KeyInfoFactory kif = fac.getKeyInfoFactory(); 
KeyName kv = kif.newKeyName("owlstead"); 
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

Je ne pouvais pas vérifier votre code en raison d'un problème en utilisant "#_0" comme une référence sur ma machine bien.

Bien sûr, vous devrez également distribuer de manière sécurisée la clé HMAC. Juste le générer au hasard n'est probablement pas bon. C'est un sujet différent cependant.