X.509 Android中的数字签名实现

时间:2016-04-21 07:14:34

标签: java android digital-signature xml-signature pkcs#12

我正在尝试在我的Android应用程序中生成X.509数字签名。

但我收到此错误

Error:trouble processing "javax/xml/crypto/AlgorithmMethod.class":
    Error:Ill-advised or mistaken usage of a core class (java.* or javax.*)

因为我在我的IDE中使用了javax文件和android SDK。

是否有可能解决此错误,或者在Android中有其他替代方式创建数字签名吗?

这里我尝试过:

public class XmlSigner  {

    private static final String KEY_STORE_TYPE = "PKCS12";
    private static final String MEC_TYPE = "DOM";
    private static final String WHOLE_DOC_URI = "";
    private KeyStore.PrivateKeyEntry keyEntry;
    XmlSigner(String inputXML){


       String storeFile  = Environment.getExternalStorageDirectory()+"/Download/"+"myP12file.p12";
        this.keyEntry =getKeyFromKeyStore(storeFile,"password".toCharArray(),"password");

        if (keyEntry == null) {
            throw new RuntimeException("Key could not be read for digital signature. Please check value of signature "
                    + "alias and signature password, and restart the Auth Client");
        }

        String xmlValue = signXML(inputXML,true);
        Log.e("vsaue","value");
    }

    public String signXML(String xmlDocument, boolean includeKeyInfo) {
        Security.addProvider(new BouncyCastleProvider());
        try {
            // Parse the input XML
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Document inputDocument = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlDocument)));

            // Sign the input XML's DOM document
            Document signedDocument = sign(inputDocument, includeKeyInfo);

            // Convert the signedDocument to XML String
            StringWriter stringWriter = new StringWriter();
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer trans = tf.newTransformer();
            trans.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, boolean includeKeyInfo) throws Exception {

        // Creating the XMLSignature factory.
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance(MEC_TYPE);
        // Creating the reference object, reading the whole document for
        // signing.

            javax.xml.crypto.dsig.Reference ref = fac.newReference(WHOLE_DOC_URI, fac.newDigestMethod(DigestMethod.SHA1, null),
                    Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null,
                    null);


        // Create the SignedInfo.
        SignedInfo sInfo = fac.newSignedInfo(
                fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
                fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));

        if (keyEntry == null) {
            throw new RuntimeException(
                    "Key could not be read for digital signature. Please check value of signature alias and signature password, and restart the Auth Client");
        }

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

        KeyInfo kInfo = getKeyInfo(x509Cert, fac);
        DOMSignContext dsc = new DOMSignContext(this.keyEntry.getPrivateKey(), xmlDoc.getDocumentElement());
        XMLSignature signature = fac.newXMLSignature(sInfo, includeKeyInfo ? kInfo : null);
        signature.sign(dsc);

        Node node = dsc.getParent();
        return node.getOwnerDocument();

    }

    @SuppressWarnings("unchecked")
    private KeyInfo getKeyInfo(X509Certificate cert, XMLSignatureFactory fac) {
        // 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);
        return kif.newKeyInfo(Collections.singletonList(xd));
    }
    private KeyStore.PrivateKeyEntry getKeyFromKeyStore(String keyStoreFile, char[] keyStorePassword, String alias) {
        // Load the KeyStore and get the signing key and certificate.
        FileInputStream keyFileStream = null;
        try {

            KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
            keyFileStream = new FileInputStream(keyStoreFile);
            ks.load(keyFileStream, keyStorePassword);

            KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
                    new KeyStore.PasswordProtection(keyStorePassword));
            return entry;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (keyFileStream != null) {
                try {
                    keyFileStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

我在我的应用程序中创建了一个用于创建数字签名的XMLSigner类。

现在我使用xmlsec-1.4.1.jar文件来使用XMLSignatureFactoryBouncyCastle

运行时出错:

Error:trouble processing "javax/xml/crypto/AlgorithmMethod.class":
Error:Ill-advised or mistaken usage of a core class (java.* or javax.*)
Error:when not building a core library.
Error:This is often due to inadvertently including a core library file
Error:in your application's project, when using an IDE (such as
Error:Eclipse). If you are sure you're not intentionally defining a
Error:core class, then this is the most likely explanation of what's
Error:going on.
Error:However, you might actually be trying to define a class in a core
Error:namespace, the source of which you may have taken, for example,
Error:from a non-Android virtual machine project. This will most
Error:assuredly not work. At a minimum, it jeopardizes the
Error:compatibility of your app with future versions of the platform.
Error:It is also often of questionable legality.
Error:If you really intend to build a core library -- which is only
Error:appropriate as part of creating a full virtual machine
Error:distribution, as opposed to compiling an application -- then use
Error:the "--core-library" option to suppress this error message.
Error:If you go ahead and use "--core-library" but are in fact
Error:building an application, then be forewarned that your application
Error:will still fail to build or run, at some point. Please be
Error:prepared for angry customers who find, for example, that your
Error:application ceases to function once they upgrade their operating
Error:system. You will be to blame for this problem.
Error:If you are legitimately using some code that happens to be in a
Error:core package, then the easiest safe alternative you have is to
Error:repackage that code. That is, move the classes in question into
Error:your own package namespace. This means that they will never be in
Error:conflict with core system classes. JarJar is a tool that may help
Error:you in this endeavor. If you find that you cannot do this, then
Error:that is an indication that the path you are on will ultimately
Error:lead to pain, suffering, grief, and lamentation.
Error:1 error; aborting
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: java.lang.RuntimeException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Program Files\Java\jdk1.7.0_79\bin\java.exe'' finished with non-zero exit value 1 

感谢。

0 个答案:

没有答案