首页 > 解决方案 > 在 Keystore 初始化期间,Java 无法读取存储在 Oracle Blob 列中的 .p12 文件

问题描述

我正在尝试在 Oracle 数据库模式中使用 Java 执行非常见功能,但几周后我被奇怪的 Java 行为所困扰。

我想要的功能

我想使用存储在同一数据库模式中的 Oracle PL/SQL 过程和 Java 类在 XML 文档上应用数字签名(使用预先存在的 p12 证书文件)(我试图避免使用外部 API/Web 服务进行数字签名功能)。

上下文信息

这是解决方案设计的简要概述: 1. 我想使用存储在同一个 Oracle 数据库实例中的 java 类 2. 我想从 PL/SQL 调用 java 类 3. 主要的签名功能将发生在 Java 类中,这将连接到 Oracle 数据库 a 获取两个 Blob 文件:数字证书作为 p12 文件存储在一个 Blob 列中,要签名的 XML 文件存储在另一个 Blob 列中。

问题

经过几次测试,我发现了一个奇怪的 java 行为。Java可以毫无问题地读取 Blob 列的内容(它可以探索 Blob 的大小、打印内容等)

但是当我尝试使用 Blob 列(包含 p12 文件的列)作为 Keystore 类的 InputStream 时,java无法将证书加载到 Keystore 中。

这是一段代码,只是为了看看您是否对如何强制 Keystore 类读取 Blob 的内容作为输入有任何想法......

public static String Blob_X509Cert_Test() {
    String v_hilera = null;
    try {
         Connection con = DriverManager.getConnection
                          ("jdbc:oracle:thin:@myserver:15210:mysid",
                            "myuseraccount","mypassword");
         Statement stmt=con.createStatement();
         ResultSet rs = stmt.executeQuery("select blob_cert from tmp_blob");
         if (rs.next()) {
            Blob v_blob = rs.getBlob("blob_cert");
            InputStream v_is = v_blob.getBinaryStream();
            int v_b = v_is.read();
            KeyStore p12;
            try {
                 p12 = KeyStore.getInstance("pkcs12");
                 try {
                      p12.load(v_is, "p12password".toCharArray());
                      Enumeration<String> e = p12.aliases();
                      while (e.hasMoreElements()) {
                             String alias = (String) e.nextElement();
                             X509Certificate c = (X509Certificate)
                                                 p12.getCertificate(alias);
                             Principal subject = c.getSubjectDN();
                             String subjectArray[] =
                                        subject.toString().split(",");
                             for (String s : subjectArray) {
                                  String[] str = s.trim().split("=");
                                  String key = str[0];
                                  String value = str[1];
                             }
                 }
            } catch (NoSuchAlgorithmException | CertificateException e1) {
                    e1.printStackTrace();
            }
         } catch (KeyStoreException e1) {
                  e1.printStackTrace();
    }
    return v_hilera;
}

这段代码可能不完整(我把它放在这里只是为了帮助理解概念,但如果有必要我准备分享更多代码)。

在我的研究中,我将问题隔离为无法读取 Blob 内容的 Keystore.load() 方法(也许问题可能出在另一个站点上)。

如果我使用本地文件系统作为 Keystore.load() 的输入流,一切都会按预期工作......

如果您尝试这段代码:

FileInputStream v_fis = new FileInputStream("C:/temp/TD_Cramos_Test.p12");
System.out.println("v_fis.available(): " + v_fis.available());

结果:6736(文件内容的大小)

如果您尝试相同的功能但使用Blob “文件”,结果将是cero字节:

InputStream v_is = v_blob.getBinaryStream();
System.out.println("v_is.available(): " + v_is.available());    

结果:0(由于某种原因,没有读取 blob 内容)

任何帮助或指导将不胜感激,

卡洛斯。

标签: javaoracleblob

解决方案


推荐阅读