001package org.hl7.fhir.dstu2.utils; 002 003/*- 004 * #%L 005 * org.hl7.fhir.dstu2 006 * %% 007 * Copyright (C) 2014 - 2019 Health Level 7 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023 024import java.io.ByteArrayInputStream; 025import java.io.IOException; 026import java.io.OutputStream; 027import java.security.InvalidAlgorithmParameterException; 028import java.security.KeyException; 029import java.security.KeyPair; 030import java.security.KeyPairGenerator; 031import java.security.NoSuchAlgorithmException; 032import java.util.Collections; 033 034import javax.xml.crypto.MarshalException; 035import javax.xml.crypto.dsig.CanonicalizationMethod; 036import javax.xml.crypto.dsig.DigestMethod; 037import javax.xml.crypto.dsig.Reference; 038import javax.xml.crypto.dsig.SignatureMethod; 039import javax.xml.crypto.dsig.SignedInfo; 040import javax.xml.crypto.dsig.Transform; 041import javax.xml.crypto.dsig.XMLSignature; 042import javax.xml.crypto.dsig.XMLSignatureException; 043import javax.xml.crypto.dsig.XMLSignatureFactory; 044import javax.xml.crypto.dsig.dom.DOMSignContext; 045import javax.xml.crypto.dsig.keyinfo.KeyInfo; 046import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; 047import javax.xml.crypto.dsig.keyinfo.KeyValue; 048import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; 049import javax.xml.crypto.dsig.spec.TransformParameterSpec; 050import javax.xml.parsers.DocumentBuilder; 051import javax.xml.parsers.DocumentBuilderFactory; 052import javax.xml.parsers.ParserConfigurationException; 053 054import org.hl7.fhir.exceptions.FHIRException; 055import org.hl7.fhir.utilities.xml.XmlGenerator; 056import org.w3c.dom.Document; 057import org.xml.sax.SAXException; 058 059public class DigitalSignatures { 060 061 062 public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyException, MarshalException, XMLSignatureException, FHIRException { 063 // http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html 064 // 065 byte[] inputXml = "<Envelope xmlns=\"urn:envelope\">\r\n</Envelope>\r\n".getBytes(); 066 // load the document that's going to be signed 067 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 068 dbf.setNamespaceAware(true); 069 DocumentBuilder builder = dbf.newDocumentBuilder(); 070 Document doc = builder.parse(new ByteArrayInputStream(inputXml)); 071 072 // create a key pair 073 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 074 kpg.initialize(512); 075 KeyPair kp = kpg.generateKeyPair(); 076 077 // sign the document 078 DOMSignContext dsc = new DOMSignContext(kp.getPrivate(), doc.getDocumentElement()); 079 XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); 080 081 Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null); 082 SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); 083 084 KeyInfoFactory kif = fac.getKeyInfoFactory(); 085 KeyValue kv = kif.newKeyValue(kp.getPublic()); 086 KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 087 XMLSignature signature = fac.newXMLSignature(si, ki); 088 signature.sign(dsc); 089 090 OutputStream os = System.out; 091 new XmlGenerator().generate(doc.getDocumentElement(), os); 092 } 093}