Javaの脆弱性である CVE-2022-21449 が巷で話題・問題になってますが、
CVE-2022-21449は、ECDSA(楕円曲線デジタル署名アルゴリズム)のJavaの実装に欠陥があるため、不正なデジタル署名に対する検証が 誤って成功してしまう
というものです。
この脆弱性に関して、結局どの Java バージョンが影響を受けるのかについて、情報が錯綜しているようです。
ネットの情報の正しさを調べるのも面倒なので、どのJavaが影響を受けるのかはコードを書けば一応わかります。
検証用のコード
以下は、CVE-2022-21449が該当するJavaバージョンであるかを検証できるコードになります (IEEE P1363 の署名形式)
import java.security.*; public class SignatureVerifyCheck { public static void main(String[] args) { // どのJava使ってるのか確認 System.out.println(System.getProperty("java.vendor") + " : " + System.getProperty("java.version")); KeyPair keyPair; try { // Elliptic Curveアルゴリズムのキー・ペアを生成します。 keyPair = KeyPairGenerator.getInstance("EC").generateKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return; } System.out.println(keyPair); // ECDSAシグネチャ・アルゴリズム(IEEE P1363 の署名形式) // NONEwithECDSAinP1363Format / SHA1withECDSAinP1363Format / SHA224withECDSAinP1363Format / // SHA256withECDSAinP1363Format / SHA384withECDSAinP1363Format / SHA512withECDSAinP1363Format Signature ecdsaSignature; try { ecdsaSignature = Signature.getInstance("SHA256withECDSAinP1363Format"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return; } System.out.println(ecdsaSignature); // 不正な署名の代わりとなる値 byte[] blankSignature = new byte[64]; try { // 署名オブジェクトを、検証操作のために指定された公開鍵で初期化します ecdsaSignature.initVerify(keyPair.getPublic()); // 署名検証する対象をセットする ecdsaSignature.update("Hello, World".getBytes()); // ※渡された署名を検証する。 署名が正しく検証されたなら true, そうでなければ false が返される はずだが... boolean verifyResult = ecdsaSignature.verify(blankSignature); System.out.println("Invalid Signature verify result : " + verifyResult); // ※不正な署名なら false となるはず } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } } }
このコードの実行結果 で Invalid Signature verify result : true
というものが出力されてしまうと、脆弱性の影響を受ける Java であることがわかります。
IEEE P1363 の署名形式 が使えない古いバージョンのJavaの場合以下の ASN.1 DER 署名形式を利用したコードで確認できます
import java.security.*; public class SignatureVerifyCheck { public static void main(String[] args) { // どのJava使ってるのか確認 System.out.println(System.getProperty("java.vendor") + " : " + System.getProperty("java.version")); KeyPair keyPair; try { // Elliptic Curveアルゴリズムのキー・ペアを生成します。 keyPair = KeyPairGenerator.getInstance("EC").generateKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return; } System.out.println(keyPair); // ECDSAシグネチャ・アルゴリズム (ASN.1 DER 署名) // NONEwithECDSA / SHA1withECDSA / SHA224withECDSA / // SHA256withECDSA / SHA384withECDSA / SHA512withECDSA ... Signature ecdsaSignature; try { ecdsaSignature = Signature.getInstance("SHA256withECDSA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return; } System.out.println(ecdsaSignature); // 不正な署名の代わりとなる値 (ASN.1 DER 用) byte[] invalidSignature = new byte[]{ 0x30, 6, 2, 1, 0, 2, 1, 0 }; try { // 署名オブジェクトを、検証操作のために指定された公開鍵で初期化します ecdsaSignature.initVerify(keyPair.getPublic()); // 署名検証する対象をセットする ecdsaSignature.update("Hello, World".getBytes()); // ※渡された署名を検証する。 署名が正しく検証されたなら true, そうでなければ false が返される はずだが... boolean verifyResult = ecdsaSignature.verify(invalidSignature); System.out.println("Invalid Signature verify result : " + verifyResult); // ※不正な署名なら false となるはず } catch (InvalidKeyException e) { e.printStackTrace(); } catch (SignatureException e) { e.printStackTrace(); } } }
いくつかのJavaで試した結果
いくつかの Java で実際に試してみて、結果がどうなるかを確認しました。
Eclipse Adoptium (AdoptOpenJDK) - 1.8.0_322
Temurin : 1.8.0_322 java.security.KeyPair@deb6432 Signature object: SHA256withECDSA<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
Eclipse Adoptium (AdoptOpenJDK) - 11.0.14.1
Eclipse Adoptium : 11.0.14.1 java.security.KeyPair@371a67ec Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
Eclipse Adoptium (AdoptOpenJDK) - 17.0.2
Eclipse Adoptium : 17.0.2 java.security.KeyPair@7a79be86 Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : true
最終的な結果が true
となっているので 脆弱性の影響を受けます
Amazon corretto - 1.8.0_332
Amazon.com Inc. : 1.8.0_332 java.security.KeyPair@3581c5f3 Signature object: SHA256withECDSA<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
Amazon corretto - 11.0.14.1
Amazon.com Inc. : 11.0.14.1 java.security.KeyPair@eafc191 Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
Amazon corretto - 17.0.2
Amazon.com Inc. : 17.0.2 java.security.KeyPair@1d251891 Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : true
最終的な結果が true
となっているので 脆弱性の影響を受けます
Amazon corretto - 17.0.3
Amazon.com Inc. : 17.0.3 java.security.KeyPair@3f3afe78 Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません(脆弱性に対する修正が行われています)
Oracle OpenJDK - 17.0.2
Oracle Corporation : 17.0.2 java.security.KeyPair@2752f6e2 Signature object: SHA256withECDSAinP1363Format<not initialized> Invalid Signature verify result : true
最終的な結果が true
となっているので 脆弱性の影響を受けます
Oracle JDK - 1.7.0_80
Oracle Corporation : 1.7.0_80 java.security.KeyPair@60dd1773 Signature object: SHA256withECDSA<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
Oracle JDK - 1.8.0_201
Oracle Corporation : 1.8.0_201 java.security.KeyPair@7daf6ecc Signature object: SHA256withECDSA<not initialized> Invalid Signature verify result : false
最終的な結果が false
となっているので 脆弱性の影響を受けません
まとめ
いくつかの環境で脆弱性の影響を受けることが確認できました。
また、既に修正済みのバージョンや、そもそも対象の署名アルゴリズムが使えないバージョンも確認できました。