成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

在XMLSignature中使用BouncyCastle做RSA

LiangJ / 1008人閱讀

Abstract

There is an article shows demo code for making XMLSignature by using Java XML Digital Signature API, where it actually uses org.jcp.xml.dsig.internal.dom.XMLDSigRI to do DOM formation, and the first provider in the java.security lookup order that will support SHA1 digestion, SHA1withRSA signing to do algorithm jobs.

DEBUG the code

Firstly, just copy the code from the article,

// 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,
// you 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
 ("", 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.INCLUSIVE,
   (C14NMethodParameterSpec) null),
    fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
     Collections.singletonList(ref));

// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("mykeystore.jks"), "changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
    (KeyStore.PrivateKeyEntry) ks.getEntry
        ("mykey", new KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

// Instantiate the document to be signed.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse
    (new FileInputStream("purchaseOrder.xml"));

// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature"s parent element.
DOMSignContext dsc = new DOMSignContext
    (keyEntry.getPrivateKey(), 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);


// Output the resulting document.
OutputStream os = new FileOutputStream("signedPurchaseOrder.xml");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));

follow the code comments, it is clearly several parts to making the job done, the key line is signature.sign(dsc);;

Secondly, debuging into the sign method, you will notice such as,

digestReference, digest invocations

that is for Message Digest

sign invocation

that is for Signature signing.

If you want to supply another provider to do the signing, you will have to implements the interface SignatureMethod, or extends the abstract class DOMSignatureMethod. However, the sign method in DOMSignatureMethod as you will override, is a little more complicated, even coupled with org.jcp.xml.dsig.internal.dom.SignatureProvider, and must take care of DOM structure yourself.

use apache xmlsec

The apache xmlsec has supply boilerplate code to do XMLSignature, but in a more clearly style,

public String signWithKeyPair(String sourceXml, KeyPair kp) throws Exception {
    PrivateKey privateKey = kp.getPrivate();
    Document doc = null;
    try (InputStream is = new ByteArrayInputStream(sourceXml.getBytes(Charset.forName("utf-8")))) {
        doc = MyXMLUtils.read(is, false);
    }

    Element root = doc.getDocumentElement();

    Element canonElem =
            XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);
    canonElem.setAttributeNS(
            null, Constants._ATT_ALGORITHM, Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS
    );

    SignatureAlgorithm signatureAlgorithm =
            new SignatureAlgorithm(doc, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
    XMLSignature sig =
            new XMLSignature(doc, null, signatureAlgorithm.getElement(), canonElem);

    root.appendChild(sig.getElement());
    Transforms transforms = new Transforms(doc);
    transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
    sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);

    sig.addKeyInfo(kp.getPublic());
    sig.sign(privateKey);

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    XMLUtils.outputDOMc14nWithComments(doc, bos);
    return new String(bos.toByteArray(), "utf-8");
}

If use xmlsec and want to supply your own Provider to make signature, it will be less effort to hook into the Architecture. and also making more sense when you extends SignatureAlgorithm class, supply your engine to override the following methods,

    @Override
    public void update(byte[] input) throws XMLSignatureException {
        try {
            engine.update(input);
        } catch (SignatureException e) {
            throw new XMLSignatureException(e);
        }
    }

    @Override
    public void update(byte input) throws XMLSignatureException {
        try {
            engine.update(input);
        } catch (SignatureException e) {
            throw new XMLSignatureException(e);
        }
    }

    @Override
    public void update(byte[] buf, int offset, int len) throws XMLSignatureException {
        try {
            engine.update(buf, offset, len);
        } catch (SignatureException e) {
            throw new XMLSignatureException(e);
        }
    }

    @Override
    public void initSign(Key signingKey) throws XMLSignatureException {
        try {
            engine.initSign((PrivateKey) signingKey);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void initSign(Key signingKey, SecureRandom secureRandom) throws XMLSignatureException {
        try {
            engine.initSign((PrivateKey) signingKey, secureRandom);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void initSign(Key signingKey, AlgorithmParameterSpec algorithmParameterSpec) throws XMLSignatureException {
        throw new XMLSignatureException("unsupported operation");
    }

    @Override
    public byte[] sign() throws XMLSignatureException {
        try {
            return engine.sign();
        } catch (SignatureException e) {
            throw new XMLSignatureException(e);
        }
    }

    @Override
    public void initVerify(Key verificationKey) throws XMLSignatureException {
        try {
            engine.initVerify((PublicKey) verificationKey);
        } catch (InvalidKeyException e) {
            throw new XMLSignatureException(e);
        }
    }

    @Override
    public boolean verify(byte[] signature) throws XMLSignatureException {
        try {
            return engine.verify(signature);
        } catch (SignatureException e) {
            throw new XMLSignatureException(e);
        }

    }

not need to take care of the DOM structure any more.

use Bouncy Castle Provider

Making this post more specific, I will show more codes about extends SignatureAlgorithm class along with using the engine from Bouncy Castle Provider.

public class BcSignatureAlgorithm extends AbstractSignatureAlgorithm {

    protected Signature engine;
    protected static BouncyCastleProvider provider = new BouncyCastleProvider();
    public BcSignatureAlgorithm(Document doc, String algorithmURI) throws XMLSecurityException {
        super(doc, algorithmURI);
        initEngine();
    }

    public BcSignatureAlgorithm(Document doc, String algorithmURI, int hmacOutputLength) throws XMLSecurityException {
        super(doc, algorithmURI, hmacOutputLength);
        initEngine();
    }

    public BcSignatureAlgorithm(Element element, String baseURI) throws XMLSecurityException {
        super(element, baseURI);
        initEngine();
    }

    public BcSignatureAlgorithm(Element element, String baseURI, boolean secureValidation) throws XMLSecurityException {
        super(element, baseURI, secureValidation);
        initEngine();
    }

    protected void initEngine() throws XMLSecurityException {
        try {
            engine = Signature.getInstance("SHA1withRSA", provider);
        } catch (NoSuchAlgorithmException e) {
            throw new XMLSignatureException(e);
        }
    }
}

nothing more, call the SPI getInstance method to get the engine object.
How to use the BcSignatureAlgorithm?

public String signWithCert(String sourceXml, PrivateKey privateKey, X509Certificate signingCert) throws Exception {

    Document doc = null;
    try (InputStream is = new ByteArrayInputStream(sourceXml.getBytes(Charset.forName("utf-8")))) {
        doc = MyXMLUtils.read(is, false);
    }

    Element root = doc.getDocumentElement();

    Element canonElem =
            XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);
    canonElem.setAttributeNS(
            null, Constants._ATT_ALGORITHM, Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS
    );

    AbstractSignatureAlgorithm signatureAlgorithm =
            new BcSignatureAlgorithm(doc, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);//use BcSignatureAlgorithm
    XMLSignature sig =
            new XMLSignature(doc, null, signatureAlgorithm.getElement(), canonElem);

    root.appendChild(sig.getElement());
    Transforms transforms = new Transforms(doc);
    transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
    sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);

    //sig.addKeyInfo(signingCert);
    X509Data x509data = new X509Data(doc);
    x509data.addCertificate(signingCert);

    sig.getKeyInfo().addKeyName(signingCert.getSerialNumber().toString());
    sig.getKeyInfo().add(x509data);
    //sig.sign(privateKey);
    signatureAlgorithm.doSign(privateKey,sig.getSignedInfo());
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    XMLUtils.outputDOMc14nWithComments(doc, bos);
    return new String(bos.toByteArray(), "utf-8");
}

AbstractSignatureAlgorithm will finished the jobs that XMLSignature.sign(PrivateKey) used to do, actually doSign method copy lines from it, and make sure the signature value should set to SignatureValue Element as a text node element. Last but not least, thought BcSignatureAlgorithm is behind the sight, it has used the engine from the Bouncy Castle and produce the signature.

For More Information

Programming With the Java XML Digital Signature API

xml-sec

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77043.html

相關(guān)文章

  • javax.crypto.Cipher 源碼學(xué)習(xí)筆記

    摘要:源碼學(xué)習(xí)筆記該類是用來(lái)加密的引擎類,支持對(duì)稱和非對(duì)稱加密。函數(shù)創(chuàng)建對(duì)象操作其中方法是在中操作的方法,其他幾個(gè)都使用執(zhí)行。狀態(tài)變化內(nèi)部類內(nèi)部類是用來(lái)解析中傳入的字符串的。查詢時(shí),也會(huì)查詢別名是否等于。知其然知其所以然。 javax.crypto.Cipher 源碼學(xué)習(xí)筆記 該類是JCE用來(lái)加密的引擎類,支持對(duì)稱和非對(duì)稱加密。該類的介紹可以參考:[[譯]JCA參考指南(二):核心類和接口]...

    余學(xué)文 評(píng)論0 收藏0
  • java.security.Provider 源碼學(xué)習(xí)筆記

    摘要:內(nèi)部類提供本服務(wù)的服務(wù)的類型算法名稱本服務(wù)的實(shí)現(xiàn)類的名稱別名列表空如果服務(wù)沒(méi)有別名屬性映射空如果實(shí)現(xiàn)沒(méi)有屬性以的算法為例輸出的結(jié)果其中查看支持的密鑰類型繼承類函數(shù)前三種是類的全路徑名稱帶有后三種中的方法返回中所有的條目返回中所有的條目中 java.security.Provider 內(nèi)部類Service /** * Construct a new service. * * @param...

    quietin 評(píng)論0 收藏0
  • Java代碼使用BC庫(kù)org.bouncycastle.openssl.PEMWriter 的 代

    摘要:本文為翻譯和轉(zhuǎn)載自以下是顯示如何使用的最佳投票示例。這些示例是從開(kāi)源項(xiàng)目中提取的。您可以對(duì)您喜歡的示例進(jìn)行投票,您的投票將在我們的系統(tǒng)中使用,以生成更多好的示例。示例十九生成證書(shū)并存為格式和格式 本文為翻譯和轉(zhuǎn)載自 :https://www.programcreek.com/... 以下是顯示如何使用 org.bouncycastle.openssl.PEMWriter 的最佳投票...

    史占廣 評(píng)論0 收藏0
  • 慕課網(wǎng)_《Java實(shí)現(xiàn)非對(duì)稱加密》學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期三說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。秘密密鑰,生成一個(gè)分組的秘密密鑰。 時(shí)間:2017年4月12日星期三說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:概述 1-1 概述 非對(duì)稱...

    dailybird 評(píng)論0 收藏0
  • 慕課網(wǎng)_《Java實(shí)現(xiàn)消息摘要算法加密》學(xué)習(xí)總結(jié)

    時(shí)間:2017年4月10日星期一說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:概述 1-1 Java實(shí)現(xiàn)消息摘要算法加密 消息摘要算法 MD(Message Digest) SHA(Secure H...

    zengdongbao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<