Jipher JCE 與原生映像檔

Jipher JCE 是 Oracle 開發的 Java 加密架構 (JCA) 提供者,它封裝了預先配置且經過 FIPS 驗證的 OpenSSL 3.0 版本。Jipher 提供者支援 FIPS 允許的演算法,包括 OpenSSL 3.0 的 FIPS 提供者。與 Bouncy Castle 或預設 JDK 提供者相比,Jipher 提供具有競爭力的效能。建議在僅應使用 FIPS 允許的演算法的情況下,啟用 Jipher 與原生映像檔。請注意,FIPS 僅允許在特定用例中使用某些演算法。因此,Jipher 提供的一些演算法可能不被 FIPS 允許用於所有目的。

注意:Jipher 在 GraalVM 社群版中不可用。它在 Linux 和 macOS (macOS 10.15 及更高版本) 上的 AMD64 和 AArch64 架構上都支援。

Jipher JAR 檔案包含在 Oracle GraalVM 核心套件中的:lib/jipher/jipher-jce.jarlib/jipher/jipher-pki.jar。若要啟用 Jipher,請在應用程式類別路徑上傳遞這些 JAR 檔案。

本頁說明如何將 Jipher 與 GraalVM 原生映像檔搭配使用。

使用 Jipher 建置原生執行檔 #

JCA 演算法依賴反射。為了在預先編譯期間將所有需要的程式碼路徑包含在原生執行檔中,native-image 工具需要透過反射瞭解在執行階段動態存取的任何 Java 程式碼,以及可能調用的原生程式碼。(在此深入瞭解)。這可以透過提供基於 JSON 的由代理程式收集的中繼資料來完成。代理程式也會自動註冊任何透過 Jipher 動態存取的 JCA 服務。

以下步驟說明如何使用執行一些基於 RSA 的簽章建立和驗證的簡單 Java 應用程式,將 Jipher 嵌入原生執行檔中。

  1. 將以下程式碼儲存到名為 JipherExample.java 的檔案中

     import java.security.*;
     import java.util.*;
     import com.oracle.jipher.provider.*;
    
     class JipherExample {
         public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
             Provider jipher = new JipherJCE();
             Security.insertProviderAt(jipher, 1);
    
             byte[] data = new byte[1024];
             new Random().nextBytes(data);
    
             KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", jipher);
             keyGen.initialize(4096);
             KeyPair keypair = keyGen.generateKeyPair();
                
             Signature signer = Signature.getInstance("SHA512withRSA", jipher);
             signer.initSign(keypair.getPrivate());
             signer.update(data);
             byte[] signature = signer.sign();
                
             Signature verifier = Signature.getInstance("SHA512withRSA", jipher);
             verifier.initVerify(keypair.getPublic());
             verifier.update(data);
             boolean isValid = verifier.verify(signature);
             assert(isValid);
         }
     }
    
  2. 在類別路徑上使用 Jipher JAR 檔案編譯應用程式

     javac -cp $GRAALVM_HOME/lib/jipher/jipher-jce.jar:$GRAALVM_HOME/lib/jipher/jipher-pki.jar JipherExample.java
    
  3. 在啟用代理程式的情況下,在 JVM 上執行應用程式。追蹤代理程式會擷取並寫下在測試執行期間遇到的所有動態功能到多個 *-config.json 檔案中。

     java -cp $GRAALVM_HOME/lib/jipher/jipher-jce.jar:$GRAALVM_HOME/lib/jipher/jipher-pki.jar:. -agentlib:native-image-agent=config-output-dir=<path> JipherExample
    

    其中 <path> 應指向儲存組態檔的目錄。建議輸出目錄為 /META-INF/native-image/ (如果您使用 Maven 或 Gradle 進行建置,則為 /resources/META-INF/native-image/)。稍後,在建置原生執行檔時,native-image 建置器會自動從該位置挑選檔案。

    對於此 Java 應用程式,代理程式會建立 reachability-metadata.json 檔案,其內容如下

     {
       "reflection":[
         {
           "type":"com.oracle.jipher.internal.spi.KeyPairGen$Rsa",
           "methods":[{"name":"<init>","parameterTypes":[] }]
         },
         {
           "type":"com.oracle.jipher.internal.spi.RsaDigestSig$Sha512WithRsa",
           "methods":[{"name":"<init>","parameterTypes":[] }]
         }
       ],
       "resources":[
         {"glob":"libs/linux_x64/fips.so.crc32"},
         {"glob":"libs/linux_x64/fips.so"},
         {"glob":"libs/linux_x64/libjipher.so.crc32"},
         {"glob":"libs/linux_x64/libjipher.so"},
         {"glob":"libs/linux_x64/openssl.cnf.crc32"},
         {"glob":"libs/linux_x64/openssl.cnf"},
         {"glob":"libs"}
       ],
       "jni":[
         {"type":"[B"},
         {"type":"[[B"},
         {"type":"com.oracle.jipher.internal.openssl.JniOpenSsl"},
         {"type":"java.lang.Boolean","methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }]}
       ]
     }
    
  4. 為了讓代理程式探索所有對 Jipher 的可能呼叫,請在 JVM 上使用代理程式重新執行應用程式 (您可以根據需要多次重新執行代理程式)。這將重新產生整個組態套件,包括任何負面測試案例 (以便擷取例外類別)。對於後續執行,請使用此命令

     java -agentlib:native-image-agent=config-merge-dir=<path> JipherExample
    

    config-merge-dir 命令會將新組態與先前測試執行的組態合併。

  5. 使用提供的組態建置原生執行檔

     native-image JipherExample
    

    如果組態檔已放置在 /META-INF/native-image/ 以外的其他目錄中,請在建置時傳遞此旗標 -H:ConfigurationFileDirectories=<path>,以告知 native-image 工具新的位置

     native-image -H:ConfigurationFileDirectories=<path> JipherExample
    
  6. 執行原生執行檔

     ./jipherexample
    

當 Jipher 嵌入原生執行檔中,而是由 JVM 載入時,它會將 JAR 中嵌入的原生程式庫和 openssl.cnf 檔案解壓縮到檔案系統,然後將它們動態載入到 JVM 程序中。當 Jipher 嵌入原生執行檔中時,它會繼續將原生程式庫和 openssl.cnf 檔案解壓縮到檔案系統,並將它們動態載入到原生程序中。當僅應使用 FIPS 允許的演算法時,建議將 Jipher 用於 GraalVM 原生映像檔。在此深入瞭解原生映像檔中的 JCA 服務支援。

與我們聯繫