Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to generate digital signature with x509 certificate?

How do we get and append x509data and x509certificate tag to the xml produced by the following code

 String providerName = System.getProperty("jsr105Provider",
   "org.jcp.xml.dsig.internal.dom.XMLDSigRI");

 XMLSignatureFactory fac =
   XMLSignatureFactory.getInstance("DOM",
   (Provider) Class.forName(providerName).newInstance());

 Reference ref =
   fac.newReference("",
       fac.newDigestMethod(DigestMethod.SHA1, null),
           Collections.singletonList(
               fac.newTransform(Transform.ENVELOPED,(XMLStructure) null)), 
       null, null);

   SignedInfo si = fac.newSignedInfo
       (fac.newCanonicalizationMethod
         (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, 
            (XMLStructure) null), 
        fac.newSignatureMethod(SignatureMethod.RSA_SHA1, 
            null),
        Collections.singletonList(ref));

   KeyPairGenerator kpg = 
       KeyPairGenerator.getInstance("RSA");
   kpg.initialize(512);
   KeyPair kp = kpg.generateKeyPair();

   KeyInfoFactory kif = fac.getKeyInfoFactory();
   KeyValue kv = kif.newKeyValue(kp.getPublic());

   KeyInfo ki = 
       kif.newKeyInfo(Collections.singletonList(kv));

   DocumentBuilderFactory dbf =
       DocumentBuilderFactory.newInstance();
   dbf.setNamespaceAware(true);
   Document doc1 = 
       dbf.newDocumentBuilder().
       parse(new FileInputStream("C:/Documents and Settings/sbtho/Desktop/downloads/samp.xml"));

   DOMSignContext dsc = new DOMSignContext
    (kp.getPrivate(), doc.getDocumentElement());


   XMLSignature signature = fac.newXMLSignature(si, ki);
      signature.sign(dsc);

   TransformerFactory tf = TransformerFactory.newInstance();
   Transformer trans = tf.newTransformer();

   trans.transform(
       new DOMSource(doc),
       new StreamResult(
           new FileOutputStream("C:/Documents and Settings/sbtho/Desktop/downloads/signedsamp.xml")));

the output of the above code looks like this and i want ti insert x509 tags inside the keyinfo tag.

   <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
  <questionset>
   <question category="graph" /> 
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
  <SignedInfo>
   <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" /> 
   <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-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>Kjgj/nVt41Q8gfDwSdfTGW42FQ8=</DigestValue> 
    </Reference>
    </SignedInfo>
      <SignatureValue>nhdbvODcXYvc5w65todyDBkVJJW/VgN3sxMjILO+qavIln0np57qSYvC6CjavLEdD5KZ0uLoD7r/ o07X9k3I5Q==</SignatureValue> 
 <KeyInfo>
 <KeyValue>
 <RSAKeyValue>
   <Modulus>qc/XQnBZ2/waPw+wUmdFiYUEY8RDLpaDn+Xmm56WoHn9jKKB0BCrYxz33q+z4O7VwQdv1eAdv9cK eTHEEpJpIQ==</Modulus> 
  <Exponent>AQAB</Exponent> 
  </RSAKeyValue>
  </KeyValue>
  </KeyInfo>
  </Signature>
  </questionset>

and how is the x509certificate created ?

like image 262
thejus_r Avatar asked Oct 04 '22 16:10

thejus_r


1 Answers

I know it's been a while since the question was asked, but I had the same issue, and I solved it, so I would like to share the solution It uses a keystore obtained from a security token using iaik pkcs tools:

the trick vas to replace the singletonList in

KeyInfo ki = 
   kif.newKeyInfo(Collections.singletonList(kv));

for a list with the certificate and the keyvalue.

the code with the whole magic (hope it helps someone):

public void generateSignatureforResumen(String originalXmlFilePath,
        String destnSignedXmlFilePath, IAIKPkcs11 pkcs11Provider_, KeyStore tokenKeyStore, String pin) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException, GeneralSecurityException, TokenException  {
    //Get the XML Document object
    Document doc = getXmlDocument(originalXmlFilePath);
    //Create XML Signature Factory
    PrivateKey signatureKey_ = null;
    PublicKey pubKey_ = null;
    X509Certificate signingCertificate_ = null;
    Boolean prik = false;
    Boolean pubk = false;
    Enumeration aliases = tokenKeyStore.aliases();
    while (aliases.hasMoreElements()) {
      String keyAlias = aliases.nextElement().toString();
      java.security.Key key = tokenKeyStore.getKey(keyAlias, pin.toCharArray());
      if (key instanceof java.security.interfaces.RSAPrivateKey) {
        Certificate[] certificateChain = tokenKeyStore.getCertificateChain(keyAlias);
        X509Certificate signerCertificate = (X509Certificate) certificateChain[0];
        boolean[] keyUsage = signerCertificate.getKeyUsage();
        // check for digital signature or non-repudiation,
        // but also accept if none is set
        if ((keyUsage == null) || keyUsage[0] || keyUsage[1]) {
          signatureKey_ = (PrivateKey) key;
          signingCertificate_ = signerCertificate;
          prik = true;
          pubKey_ = signerCertificate.getPublicKey();
          break;
        }
      } 
    }


    if (signatureKey_ == null) {
      throw new GeneralSecurityException(
          "Found no signature key. Ensure that a valid card is inserted.");
    }

     XMLSignatureFactory xmlSigFactory = XMLSignatureFactory.getInstance("DOM");
        Reference ref = null;
        SignedInfo signedInfo = null;
        try {
            ref = xmlSigFactory.newReference("", xmlSigFactory.newDigestMethod(DigestMethod.SHA1, null),
                    Collections.singletonList(xmlSigFactory.newTransform(Transform.ENVELOPED,
                    (TransformParameterSpec) null)), null, null);
            signedInfo = xmlSigFactory.newSignedInfo(
                    xmlSigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                    (C14NMethodParameterSpec) null),
                    xmlSigFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                    Collections.singletonList(ref));


        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } 
        KeyInfoFactory kif = xmlSigFactory.getKeyInfoFactory();
        X509Data x509data = kif.newX509Data(Collections.nCopies(1, signingCertificate_));
        KeyValue kval = kif.newKeyValue(pubKey_);
        List keyInfoItems = new ArrayList();
        keyInfoItems.add(kval);
        keyInfoItems.add(x509data);
        //Object list[];
        KeyInfo keyInfo = kif.newKeyInfo(keyInfoItems);
//Create a new XML Signature
    XMLSignature xmlSignature = xmlSigFactory.newXMLSignature(signedInfo, keyInfo);



    DOMSignContext domSignCtx = new DOMSignContext((Key) signatureKey_, doc.getDocumentElement());


    try {
        //Sign the document
        xmlSignature.sign(domSignCtx);
    } catch (MarshalException ex) {
        ex.printStackTrace();
    } catch (XMLSignatureException ex) {
        ex.printStackTrace();
    }
    //Store the digitally signed document inta a location
    storeSignedDoc(doc, destnSignedXmlFilePath);
like image 162
Sebastián Rudloff Avatar answered Oct 21 '22 07:10

Sebastián Rudloff