Reputation: 10959
I am generating an X509 certificate with xml signature. It is successfully generate xml digital signature.
I am using this code to generate my xml signature.
public class DigitalSigner {
private static final String KEY_STORE_TYPE = "PKCS12";
String alias;
KeyStore ks;
PrivateKey privateKey;
public DigitalSigner(String keyStoreFile, char[] keyStorePassword, String alias, Context context) {
this.alias = alias;
try {
this.ks = KeyStore.getInstance(KEY_STORE_TYPE);
this.ks.load(context.getAssets().open(keyStoreFile), keyStorePassword);
this.privateKey = (PrivateKey) this.ks.getKey(alias, keyStorePassword);
} catch (Exception e) {
Log.e("eror","erro");
e.printStackTrace();
}
}
public String signXML(String xmlDocument) {
Security.addProvider(new BouncyCastleProvider());
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
Document signedDocument = sign(dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlDocument))));
StringWriter stringWriter = new StringWriter();
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(signedDocument), new StreamResult(stringWriter));
return stringWriter.getBuffer().toString();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error while digitally signing the XML document", e);
}
}
private Document sign(Document xmlDoc) throws Exception {
X509Certificate x509Cert = (X509Certificate) this.ks.getCertificate(this.alias);
XMLSignature signature = new XMLSignature(xmlDoc, StringUtils.EMPTY, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
xmlDoc.getDocumentElement().appendChild(signature.getElement());
Transforms transforms = new Transforms(xmlDoc);
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
signature.addDocument(StringUtils.EMPTY, transforms, MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA1);
X509Data x509Data = new X509Data(xmlDoc);
signature.getKeyInfo().add(x509Data);
x509Data.addSubjectName(x509Cert.getSubjectX500Principal().getName());
x509Data.addCertificate(x509Cert);
signature.sign(this.privateKey);
return xmlDoc;
}
static {
Init.init();
// try {
// ElementProxy.setDefaultPrefix("http://www.w3.org/2000/09/xmldsig#","");
// } catch (XMLSecurityException e) {
// e.printStackTrace();
// }
}
My issue is my signature comes with a namespace prefix and I don't want to generate one.
Here is my signature:
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>JkpIdQiiPQ2KmSHyWf4ORCBGdgY=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>GkHLBqX4RUVM0JMMHxtqN93JAY/celqAlxoQ211a4IPY2dtNL668v6iZa4u870JcVz9cBYpHdHBaLb08u1clt81Wq52IymjwMXA0wSPl027CZIh+x9FPTEsoYOfaxsIn0MZsjZI8hKRNXlU5tXDDDErtW3QEQbKu2AEZTRq7rn1ocX69nj+Lv2GfFNYBlHvRPg2Z20NcARb9a4ZmOObk5C3rgU+p4GKpv0PLTmq1JSM75ftiFQ/8B7vQzEYSy0M2coTyME4pv51sdCJHIXykiv/pi0T+86RBP1VSzJ8oLUUYrGOF+4FmpoFX6pPfvbs6DiFrd4BWvsjH1YOddClWKA==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509SubjectName>CN= CORPORATION NAME 2,2.5.4.51=#13455355524154204d4148414e41474152205345564120534144414e20474f524448414e4441532043484f4b484157414c41204d415247204d55474c4953415241205355524154,STREET=STREET NAME,ST=STATE NAME,2.5.4.17=#1306333935303033,OU=MY OU NAME,O=O NAME,C=IN</ds:X509SubjectName>
<ds:X509Certificate>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</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
As you can see it has namespace prefix ds:
in it. I want to generate it without this namespace prefix.
Using crypto it is possible but Android don’t have support of following JAVA packages:
So is there any other way to do it in Android?
I have also try by removing the prefix from my namespace using this code and I am able to generate xml signature without prefix ds
but still response is 'invalid signature':
static {
Init.init();
try {
ElementProxy.setDefaultPrefix("http://www.w3.org/2000/09/xmldsig#","");
} catch (XMLSecurityException e) {
e.printStackTrace();
}
}
Upvotes: 3
Views: 971
Reputation: 45
The bug fix in java 6 version 32 related to namespace in some circumstances. In Java version 31, ds: got appended when we sign the XML (Enveloped).
7096834 xml saaj SAAJ does not set correct namespace prefix and namespace URI for attributes in some circumstances.
If you can switch to some other version then start using Java 6 version 32.
Upvotes: 0
Reputation: 2810
You need to just replace with dbf.setNamespaceAware(false); to dbf.setNamespaceAware(true);.
No need to declare Security.addProvider(new BouncyCastleProvider());, So remove that.
And make sure declare
static {
Init.init();
try {
ElementProxy.setDefaultPrefix("http://www.w3.org/2000/09/xmldsig#","");
} catch (XMLSecurityException e) {
e.printStackTrace();
}
}
Upvotes: 1