在Java映射中需要帮助来签署XML。 数字签名

2020-09-06 01:24发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


您好专家

我正在尝试使用存储在密钥库中的SSL证书对XML进行签名。 我试图使用以下代码调用证书。但是当我尝试跟踪已加载的证书时,它始终会给出nullPointer异常。

package com.nets.e2e; 导入java.io.ByteArrayOutputStream; 导入java.io.IOException; 导入java.io.InputStream; 导入java.io.OutputStream; 导入java.security.InvalidKeyException; 导入java.security.KeyStore; 导入java.security.KeyStoreException; 导入java.security.NoSuchAlgorithmException; 导入java.security.PrivateKey; 导入java.security.Security; 导入java.security.Signature; 导入java.security.UnrecoverableEntryException; 导入java.security.cert.Certificate; 导入java.security.cert.X509Certificate; 导入java.util.Date; 导入java.util.HashMap; 导入java.util.Map; 导入org.apache.commons.codec.binary.Base64; 导入javax.naming.InitialContext; 导入javax.naming.NamingException; 导入javax.xml.parsers.DocumentBuilder; 导入javax.xml.parsers.DocumentBuilderFactory; 导入javax.xml.parsers.ParserConfigurationException; 导入javax.xml.transform.OutputKeys; 导入javax.xml.transform.Transformer; 导入javax.xml.transform.TransformerConfigurationException; 导入javax.xml.transform.TransformerException; 导入javax.xml.transform.TransformerFactory; 导入javax.xml.transform.dom.DOMSource; 导入javax.xml.transform.stream.StreamResult; 导入org.w3c.dom.Document; 导入org.xml.sax.SAXException; 导入com.sap.aii.mapping.api.AbstractTrace; 导入com.sap.aii.mapping.api.AbstractTransformation; 导入com.sap.aii.mapping.api.MappingTrace; 导入com.sap.aii.mapping.api.StreamTransformationConstants; 导入com.sap.aii.mapping.api.StreamTransformationException; 导入com.sap.aii.mapping.api.TransformationInput; 导入com.sap.aii.mapping.api.TransformationOutput; 导入com.sap.aii.security.lib.KeyStoreManager; 导入com.sap.security.api.ssf.ISsfData; 导入com.sap.security.api.ssf.ISsfProfile; 导入com.sap.security.core.server.ssf.SsfDataPKCS7; 导入com.sap.security.core.server.ssf.SsfInvalidKeyException; 导入com.sap.security.core.server.ssf.SsfProfileKeyStore; 导入com.sap.aii.af.service.resource.SAPSecurityResources; 公共类XadesSignature扩展了AbstractTransformation {@SuppressWarnings(" deprecation")public void transform(TransformationInput TransformationInput,TransformationOutput TransformationOutput)throws StreamTransformationException {try {InputStream inputstream = TransformationInput.getInputPayload()。getInputStream(); OutputStream outputstream = TransformationOutput.getOutputPayload()。getOutputStream(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 文档doc = dBuilder.parse(inputstream); byte [] b =新的byte [inputstream.available()]; inputstream.read(b); ISsfData数据=新的SsfDataPKCS7(inputstream); getTrace()。addInfo(" ISsfdata对象已创建"); KeyStoreManager manager = null; manager = com.sap.aii.af.service.resource.SAPSecurityResources.getInstance()。getKeyStoreManager(com.sap.aii.security.lib.PermissionMode.SYSTEM_LEVEL); KeyStore keyStore = manager.getKeyStore(" ESigning_API_SSL");

SsfProfileKeyStore配置文件=新的SsfProfileKeyStore(keyStore," ESigning_API_SSL",null); //getTrace()。addInfo(profile.getCertificate()。getSignature()。toString()); //profile = manager.getISsfProfile(keyStore," ESigning_API_SSL",null); getTrace()。addInfo(profile.toString()); data.sign(profile); ByteArrayOutputStream baos = new ByteArrayOutputStream(); data.writeTo(baos); 字符串signedString =新字符串(baos.toByteArray()); doc.getElementsByTagName(" TrustB2BMessage")。item(0).setTextContent(signedString); doc.getDocumentElement()。normalize(); TransformerFactory TransformerFactory = TransformerFactory.newInstance(); 变压器变压器= transformerFactory.newTransformer(); DOMSource source =新的DOMSource(doc); StreamResult结果=新的StreamResult(outputstream); Transformer.setOutputProperty(OutputKeys.INDENT,"是"); Transformer.transform(来源,结果); } catch(KeyStoreException | SsfInvalidKeyException | IOException | ParserConfigurationException | SAXException | TransformerException ex){ex.printStackTrace(); } getTrace()。addInfo("程序结束"); }

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


您好专家

我正在尝试使用存储在密钥库中的SSL证书对XML进行签名。 我试图使用以下代码调用证书。但是当我尝试跟踪已加载的证书时,它始终会给出nullPointer异常。

package com.nets.e2e; 导入java.io.ByteArrayOutputStream; 导入java.io.IOException; 导入java.io.InputStream; 导入java.io.OutputStream; 导入java.security.InvalidKeyException; 导入java.security.KeyStore; 导入java.security.KeyStoreException; 导入java.security.NoSuchAlgorithmException; 导入java.security.PrivateKey; 导入java.security.Security; 导入java.security.Signature; 导入java.security.UnrecoverableEntryException; 导入java.security.cert.Certificate; 导入java.security.cert.X509Certificate; 导入java.util.Date; 导入java.util.HashMap; 导入java.util.Map; 导入org.apache.commons.codec.binary.Base64; 导入javax.naming.InitialContext; 导入javax.naming.NamingException; 导入javax.xml.parsers.DocumentBuilder; 导入javax.xml.parsers.DocumentBuilderFactory; 导入javax.xml.parsers.ParserConfigurationException; 导入javax.xml.transform.OutputKeys; 导入javax.xml.transform.Transformer; 导入javax.xml.transform.TransformerConfigurationException; 导入javax.xml.transform.TransformerException; 导入javax.xml.transform.TransformerFactory; 导入javax.xml.transform.dom.DOMSource; 导入javax.xml.transform.stream.StreamResult; 导入org.w3c.dom.Document; 导入org.xml.sax.SAXException; 导入com.sap.aii.mapping.api.AbstractTrace; 导入com.sap.aii.mapping.api.AbstractTransformation; 导入com.sap.aii.mapping.api.MappingTrace; 导入com.sap.aii.mapping.api.StreamTransformationConstants; 导入com.sap.aii.mapping.api.StreamTransformationException; 导入com.sap.aii.mapping.api.TransformationInput; 导入com.sap.aii.mapping.api.TransformationOutput; 导入com.sap.aii.security.lib.KeyStoreManager; 导入com.sap.security.api.ssf.ISsfData; 导入com.sap.security.api.ssf.ISsfProfile; 导入com.sap.security.core.server.ssf.SsfDataPKCS7; 导入com.sap.security.core.server.ssf.SsfInvalidKeyException; 导入com.sap.security.core.server.ssf.SsfProfileKeyStore; 导入com.sap.aii.af.service.resource.SAPSecurityResources; 公共类XadesSignature扩展了AbstractTransformation {@SuppressWarnings(" deprecation")public void transform(TransformationInput TransformationInput,TransformationOutput TransformationOutput)throws StreamTransformationException {try {InputStream inputstream = TransformationInput.getInputPayload()。getInputStream(); OutputStream outputstream = TransformationOutput.getOutputPayload()。getOutputStream(); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 文档doc = dBuilder.parse(inputstream); byte [] b =新的byte [inputstream.available()]; inputstream.read(b); ISsfData数据=新的SsfDataPKCS7(inputstream); getTrace()。addInfo(" ISsfdata对象已创建"); KeyStoreManager manager = null; manager = com.sap.aii.af.service.resource.SAPSecurityResources.getInstance()。getKeyStoreManager(com.sap.aii.security.lib.PermissionMode.SYSTEM_LEVEL); KeyStore keyStore = manager.getKeyStore(" ESigning_API_SSL");

SsfProfileKeyStore配置文件=新的SsfProfileKeyStore(keyStore," ESigning_API_SSL",null); //getTrace()。addInfo(profile.getCertificate()。getSignature()。toString()); //profile = manager.getISsfProfile(keyStore," ESigning_API_SSL",null); getTrace()。addInfo(profile.toString()); data.sign(profile); ByteArrayOutputStream baos = new ByteArrayOutputStream(); data.writeTo(baos); 字符串signedString =新字符串(baos.toByteArray()); doc.getElementsByTagName(" TrustB2BMessage")。item(0).setTextContent(signedString); doc.getDocumentElement()。normalize(); TransformerFactory TransformerFactory = TransformerFactory.newInstance(); 变压器变压器= transformerFactory.newTransformer(); DOMSource source =新的DOMSource(doc); StreamResult结果=新的StreamResult(outputstream); Transformer.setOutputProperty(OutputKeys.INDENT,"是"); Transformer.transform(来源,结果); } catch(KeyStoreException | SsfInvalidKeyException | IOException | ParserConfigurationException | SAXException | TransformerException ex){ex.printStackTrace(); } getTrace()。addInfo("程序结束"); }

付费偷看设置
发送
5条回答
歪着头看世界
1楼 · 2020-09-06 02:00.采纳回答

HI Rajesh,

感谢您的回复。

我的问题通过以下代码的Java映射得到解决:

包com.nets.e2e;


 导入java.security.Key;
 导入java.security。*;
 导入java.security.KeyStore;
 导入java.security.PrivateKey;
 导入java.security.PublicKey;
 导入java.util.ArrayList;
 导入java.util.Collections;
 导入java.util.List;
 导入org.w3c.dom.Node;
 导入org.w3c.dom.NodeList;
 导入com.sap.aii.mapping.api.AbstractTransformation;
 导入com.sap.aii.mapping.api.StreamTransformationException;
 导入com.sap.aii.mapping.api.TransformationInput;
 导入com.sap.aii.mapping.api.TransformationOutput;
 导入java.security.cert。*;
 导入javax.xml.crypto。*;
 导入javax.xml.crypto.dom。*;


 导入javax.xml.crypto.dsig.Reference;
 导入javax.xml.crypto.dsig.SignedInfo;
 导入javax.xml.crypto.dsig.XMLSignature;
 导入javax.xml.crypto.dsig.XMLSignatureFactory;
 导入javax.xml.crypto.dsig。*;
 导入javax.xml.crypto.dsig.dom。*;
 导入javax.xml.crypto.dsig.keyinfo.KeyInfo;
 导入javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
 导入javax.xml.crypto.dsig.keyinfo.X509Data;
 导入javax.xml.parsers.DocumentBuilderFactory;
 导入javax.xml.transform.Transformer;
 导入javax.xml.transform.TransformerFactory;
 导入javax.xml.transform.dom.DOMSource;
 导入javax.xml.transform.stream.StreamResult;


 导入java.io. *;
 导入javax.xml.transform。*;
 导入org.w3c.dom.Document;
 导入javax.xml.crypto.dsig.spec。*;


//使用system.xml;


 公共类GenerateXMLSignature扩展AbstractTransformation {


//参考链接:https://www.oracle.com/technetwork/dig-signature-api-140772.html

 公共无效transform(TransformationInput TransformationInput,TransformationOutput TransformationOutput)引发StreamTransformationException
     {


 字符串输出="";

//TODO自动生成的方法存根
 尝试{


 InputStream inputstream = TransformationInput.getInputPayload()。getInputStream();
     OutputStream outputstream = TransformationOutput.getOutputPayload()。getOutputStream();
    
 XMLSignatureFactory fac = XMLSignatureFactory.getInstance(" DOM");


 参考ref = fac.newReference("#object",
 fac.newDigestMethod(DigestMethod.SHA1,null));




 SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(" http://www.w3.org/2001/10/xml-exc-c14n#",(C14NMethodParameterSpec)null),fac.newSignatureMethod(SignatureMethod.RSA_SHA1,null)  ,Collections.singletonList(ref));

 KeyStore ks = KeyStore.getInstance(" JKS");


 ks.load(new FileInputStream("/img/usr/sap/P2D/keystore/keyname.jks")," changeit" .toCharArray());

 KeyStore.PrivateKeyEntry keyEntry =(KeyStore.PrivateKeyEntry)ks.getEntry(" key",新的KeyStore.PasswordProtection(" pwd" .toCharArray()));



 X509Certificate cert =(X509Certificate)keyEntry.getCertificate();


 KeyInfoFactory kif = fac.getKeyInfoFactory();
 列表x509Content = new ArrayList();

 x509Content.add(cert.getSubjectX500Principal()。getName());
 x509Content.add(cert);
 X509Data xd = kif.newX509Data(x509Content);
 KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 dbf.setNamespaceAware(true);

 文档doc = dbf.newDocumentBuilder()。parse(inputstream);

 文档doc1 = dbf.newDocumentBuilder()。newDocument();

 节点text1 = doc1.createTextNode("");

 doc.setXmlStandalone(true);

 DOMSource domSource =新的DOMSource(doc);
 StringWriter writer = new StringWriter();
 StreamResult结果=新的StreamResult(writer);
 TransformerFactory tf = TransformerFactory.newInstance();
 变压器变压器= tf.newTransformer();
 Transformer.transform(domSource,result);





 字符串输入= writer.toString();
 字符串signxml = input.substring(38);


 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
 builderFactory.setNamespaceAware(false);
 builderFactory.setValidating(false);


 文档document = builderFactory.newDocumentBuilder()。newDocument();

          
          
     DOMSource domSource4 =新的DOMSource(document);
 StringWriter writer4 =新的StringWriter();
 StreamResult result4 =新的StreamResult(writer4);
 TransformerFactory tf4 = TransformerFactory.newInstance();
 变压器Transformer4 = tf.newTransformer();
 Transformer4.transform(domSource4,result4);
 NodeList nl;
 节点xmlToInsert;
 节点importNode;
 节点text = null;
 if(input.contains(" Root_Message1"))
 {
 nl = doc.getElementsByTagName(" Root_Message1");

 xmlToInsert = nl.item(0);
 importNode = document.importNode(xmlToInsert,true);
 文字=((NodeList)doc.getElementsByTagName(" Root_Message1"))。item(0);
 }
 否则if(input.contains(" Root_Message"))
 {
 nl = doc.getElementsByTagName(" Root_Message2");
 xmlToInsert = nl.item(0);
 importNode = document.importNode(xmlToInsert,true);
 文字=((NodeList)doc.getElementsByTagName(" Root_Message2"))。item(0);
 }


 Source source =新的DOMSource(text);

 XMLStructure内容=新的DOMStructure(text);


 XMLObject obj = fac.newXMLObject
 (Collections.singletonList(content)," object",null,null);


 doc1.setXmlStandalone(true);
 DOMSource domSource1 =新的DOMSource(doc1);
 StringWriter writer1 =新的StringWriter();
 StreamResult result1 =新的StreamResult(writer1);
 TransformerFactory tf1 = TransformerFactory.newInstance();
 变压器Transformer1 = tf1.newTransformer();
 Transformer1.transform(domSource1,result1);






 XMLSignature签名= fac.newXMLSignature(si,ki,
 Collections.singletonList(obj),null,null);

 DOMSignContext dsc =新的DOMSignContext(keyEntry.getPrivateKey(),doc1);
 signature.sign(dsc);






 布尔verifystatus = verify(doc1);

            
            如果(verifystatus)
            {
         变压器trans = tf.newTransformer();
        trans.setOutputProperty(OutputKeys.ENCODING," UTF-8");
        trans.transform(new DOMSource(doc1),new StreamResult(outputstream));
       
            }
           
 }
 catch(异常e)
 {
 System.out.print(" Exception" + e.getMessage());
 }


 }

 公共静态布尔验证(文档doc1)
 {
 布尔验证结果=假;
 尝试{
 DocumentBuilderFactory dbf1 = DocumentBuilderFactory.newInstance();
         dbf1.setNamespaceAware(true);
        
       
 字符串s ="";


         文档签署文档= doc1;

 NodeList nl =
 signatureDocument.getElementsByTagNameNS(XMLSignature.XMLNS," Signature");
 如果(nl.getLength()== 0){
 抛出新的Exception(" Cannot find Signature element");
 }


 XMLSignatureFactory fac1 = XMLSignatureFactory.getInstance(" DOM");

 DOMValidateContext valContext = new DOMValidateContext(GetPublicKey(),nl.item(0));


//解组XMLSignature。
 XMLSignature签名1 = fac1.unmarshalXMLSignature(valContext);



//验证XMLSignature。
 verifyResult = signature1.validate(valContext);
 }
 捕获(异常e)
         {
             System.out.println("验证数字签名时出错" + e.getMessage());
             e.printStackTrace();
         }
 返回verificationResult;

 }
 公共静态PublicKey GetPublicKey()
 {
 PublicKey publicKey = null;
 FileInputStream为= null;

 尝试
 {
 是= new FileInputStream("/img/usr/sap/P2D/keystore/key.jks");
 KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
 keystore.load(is," changeit" .toCharArray());
 字符串别名=" key";
 密钥key = keystore.getKey(alias," pwd" .toCharArray());
 如果(私钥的关键实例)
 {


 X509Certificate cert =(X509Certificate)keystore.getCertificate(alias);

//获取公钥
 publicKey = cert.getPublicKey();

 }
 }
 捕获(FileNotFoundException ex)
 {
 System.out.println(ex.getMessage());
 }
 捕获(KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | IOException ex)
 {
 System.out.println(ex.getMessage());
 }
 最后
 {
 尝试
 {
 is.close();
 }
 捕获(IOException ex)
 {
 ex.printStackTrace();
 }
 }


 返回publicKey;

 }


 }


 
代楠1984
2楼-- · 2020-09-06 01:53

嗨拉杰夫,

能否请您阐明您的要求并粘贴所用的Java映射? 我会帮你的。

感谢与问候-Rajesh PS

暮风yp
3楼-- · 2020-09-06 01:46

嗨Rajeev,

更好地排除故障并解决该错误。 检查详细的日志,并在需要时使用xpi检查器。 作为最后的选择,如果一切正常,并且系统仍然跳过签名,则可以提高OSS。 但是我认为将自定义编码作为解决方法不是一个好主意。

wang628962
4楼-- · 2020-09-06 01:42

嗨,拉维,

我尝试使用SOAP的标准功能来使用Web Service安全性设置对消息进行签名,但是似乎不起作用。 我在日志中看到" Web Service安全处理已跳过" errorlog.png

在那之后,我想用Java映射来做,但是在Java中,它也面临从密钥库读取和加载值的问题。

任何帮助将不胜感激。

谢谢!

绿领巾童鞋
5楼-- · 2020-09-06 01:55

你好,

您要使用自定义代码进行邮件签名而不使用标准邮件签名功能的任何特定原因吗?

一周热门 更多>