如何借助Java中的公钥证书验证aadhar XML签名?

发布于 2025-01-13 04:03:38 字数 2176 浏览 0 评论 0 原文

我正在研究 Aadhaar 无纸化离线 e-kyc,尝试使用公钥证书验证 aadhaar XML 签名。但我不确定这是否是正确的做法。下面是java代码供参考。

public static void validateXMLSignature() throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();

    ClassLoader classLoader = AadhaarXMLSignatureValidation.class.getClassLoader();

    
    File file1 = new File("path-to-xml-file/aadhaar.xml");
    Document document = db.parse(file1);
    document.normalizeDocument();

    // Find Signature element
    NodeList nl =
        document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
        throw new Exception("Cannot find Signature element");
    }

    FileInputStream fin = new FileInputStream("path-to-certificate-file/certificate.cer");
    CertificateFactory f = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
    PublicKey publicKey = certificate.getPublicKey();

    // Create a DOM XMLSignatureFactory that will be used to unmarshal the
    // document containing the XMLSignature
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

    // Create a DOMValidateContext and specify a X509KeySelector
    // and document context
    DOMValidateContext valContext = new DOMValidateContext(publicKey,
        nl.item(0));

    // unmarshal the XMLSignature
    XMLSignature signature = fac.unmarshalXMLSignature(valContext);

    // Validate the XMLSignature (generated above)
    boolean coreValidity = signature.validate(valContext);

    //    Check core validation status
    if (!coreValidity) {
        System.err.println("Signature failed core validation");
    } else {
        System.out.println("Signature passed core validation");
    }
}

谁能告诉我我错过了什么? 以下是 Aadhaar 无纸化离线 e-kyc 教程的链接 https://uidai.gov.in/ecosystem/authentication-devices-documents/about-aadhaar-paperless-offline-e-kyc.html

I am working on Aadhaar Paperless Offline e-kyc, trying to validate aadhaar XML signature using public key certificate. But I'm not sure is this the right way to do. Below is the java code for the reference.

public static void validateXMLSignature() throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();

    ClassLoader classLoader = AadhaarXMLSignatureValidation.class.getClassLoader();

    
    File file1 = new File("path-to-xml-file/aadhaar.xml");
    Document document = db.parse(file1);
    document.normalizeDocument();

    // Find Signature element
    NodeList nl =
        document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
    if (nl.getLength() == 0) {
        throw new Exception("Cannot find Signature element");
    }

    FileInputStream fin = new FileInputStream("path-to-certificate-file/certificate.cer");
    CertificateFactory f = CertificateFactory.getInstance("X.509");
    X509Certificate certificate = (X509Certificate)f.generateCertificate(fin);
    PublicKey publicKey = certificate.getPublicKey();

    // Create a DOM XMLSignatureFactory that will be used to unmarshal the
    // document containing the XMLSignature
    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

    // Create a DOMValidateContext and specify a X509KeySelector
    // and document context
    DOMValidateContext valContext = new DOMValidateContext(publicKey,
        nl.item(0));

    // unmarshal the XMLSignature
    XMLSignature signature = fac.unmarshalXMLSignature(valContext);

    // Validate the XMLSignature (generated above)
    boolean coreValidity = signature.validate(valContext);

    //    Check core validation status
    if (!coreValidity) {
        System.err.println("Signature failed core validation");
    } else {
        System.out.println("Signature passed core validation");
    }
}

can anyone tell me what I'm missing?
Here is the link to Aadhaar Paperless Offline e-kyc tutorial https://uidai.gov.in/ecosystem/authentication-devices-documents/about-aadhaar-paperless-offline-e-kyc.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若有似无的小暗淡 2025-01-20 04:03:38

您可以尝试使用以下方法从证书字符串中提取 X509Certificate。

private static X509Certificate getCertificateFromFile(String aadhaarCertificateString) throws GeneralSecurityException {
    CertificateFactory certFactory = CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);
    InputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(aadhaarCertificateString));
    return (X509Certificate) certFactory.generateCertificate(inputStream);
}

You can try using below method to extract X509Certificate from the certificate string.

private static X509Certificate getCertificateFromFile(String aadhaarCertificateString) throws GeneralSecurityException {
    CertificateFactory certFactory = CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);
    InputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(aadhaarCertificateString));
    return (X509Certificate) certFactory.generateCertificate(inputStream);
}
江南月 2025-01-20 04:03:38

我在验证 aadhaar XML 签名时也遇到了一些问题。只是在这里分享工作代码片段。

public static final String PEM_FILE_BEGIN = "\r\n-----BEGIN CERTIFICATE-----\r\n";

public static final String PEM_FILE_END = "\r\n-----END CERTIFICATE-----\r\n";

重要的是在公钥证书中附加 BEGIN 和 END 格式,并且它已经是 base64 字符串,因此无需对其进行解码。

public class AadhaarPaperlessOfflineEKYC {


public boolean verify() {

    String filePath = "pathTo/offlineaadhaar.xml";
    boolean verificationResult = false;

    try {

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

        Document signedDocument = dbf.newDocumentBuilder().parse(new File(filePath));

        NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        NodeList X509CertificateNodeList = signedDocument.getElementsByTagName("X509Certificate");

        if (signatureNodeList.getLength() == 0 || X509CertificateNodeList.getLength() == 0) {
            throw new IllegalArgumentException("Cannot find Signature element");
        }

        String publicKeyFile = X509CertificateNodeList.item(0).getTextContent();
        publicKeyFile = Constants.PEM_FILE_BEGIN + publicKeyFile + Constants.PEM_FILE_END;

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

        DOMValidateContext valContext = new DOMValidateContext(getCertificateFromString(publicKeyFile).getPublicKey(), signatureNodeList.item(0));
        XMLSignature signature = fac.unmarshalXMLSignature(valContext);

        verificationResult = signature.validate(valContext);

    } catch (Exception e) {
        log.error("Error while verifying digital signature: " + e);
        e.printStackTrace();
    }

    return verificationResult;
}


private static X509Certificate getCertificateFromString(String aadhaarCertificateString) throws GeneralSecurityException {
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    InputStream inputStream = new ByteArrayInputStream(aadhaarCertificateString.getBytes());
    return (X509Certificate) certFactory.generateCertificate(inputStream);
}

i also faced some issues while validating aadhaar XML signature. just sharing working code snippet here.

public static final String PEM_FILE_BEGIN = "\r\n-----BEGIN CERTIFICATE-----\r\n";

public static final String PEM_FILE_END = "\r\n-----END CERTIFICATE-----\r\n";

important is to append BEGIN and END format in public key certificate and it's already base64 string so no need to decode the same.

public class AadhaarPaperlessOfflineEKYC {


public boolean verify() {

    String filePath = "pathTo/offlineaadhaar.xml";
    boolean verificationResult = false;

    try {

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

        Document signedDocument = dbf.newDocumentBuilder().parse(new File(filePath));

        NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        NodeList X509CertificateNodeList = signedDocument.getElementsByTagName("X509Certificate");

        if (signatureNodeList.getLength() == 0 || X509CertificateNodeList.getLength() == 0) {
            throw new IllegalArgumentException("Cannot find Signature element");
        }

        String publicKeyFile = X509CertificateNodeList.item(0).getTextContent();
        publicKeyFile = Constants.PEM_FILE_BEGIN + publicKeyFile + Constants.PEM_FILE_END;

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

        DOMValidateContext valContext = new DOMValidateContext(getCertificateFromString(publicKeyFile).getPublicKey(), signatureNodeList.item(0));
        XMLSignature signature = fac.unmarshalXMLSignature(valContext);

        verificationResult = signature.validate(valContext);

    } catch (Exception e) {
        log.error("Error while verifying digital signature: " + e);
        e.printStackTrace();
    }

    return verificationResult;
}


private static X509Certificate getCertificateFromString(String aadhaarCertificateString) throws GeneralSecurityException {
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    InputStream inputStream = new ByteArrayInputStream(aadhaarCertificateString.getBytes());
    return (X509Certificate) certFactory.generateCertificate(inputStream);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文