Friday, April 18, 2014

SunJCE の Diffie-Hellman アルゴリズムで 1024 ビットを超える素数が使えない

何か問題が解決したとか, いろいろ苦労した軌跡を残したいとか, そういうわけではありません. 昨年, JCE を使って Diffie-Hellman をやってみる (27 Oct 2013) という記事で触れたことの再確認に過ぎません.

すでに Java SE 8 がリリースされてしまいましたが, まだ試していません. プライベートでは Java SE 7 を使っています. (もちろん, 仕事では, ほぼすべてのお客様が Java SE 7 すら使用禁止です. そもそも, クライアント PC も 20,000 台のうち半数は Windows XP + Internet Explorer 6 のままだという金融機関様もいらっしゃったりしますし... まあ何と言うか...)

さて, 数日前にアップデートがリリースされたので, JDK 7u55 を使って少しためしてみました.

package tt4cs.rd.crypto.dh;

import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyPairGenerator;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.spec.DHParameterSpec;
import org.junit.Test;

/**
 * 
 * @since 0.0.1-SNAPSHOT
 * @author tt4cs
 */
public class DiffieHellmanParameterSpecTest {
    
    private static final String modp1024 =
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
            "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
            "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
            "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
            "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" +
            "FFFFFFFFFFFFFFFF";
    
    private static final String modp1536 =
            "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
            "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
            "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
            "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
            "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
            "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
            "83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
            "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF";
    
    private void testWith(String modp) throws GeneralSecurityException {
        
        BigInteger p = new BigInteger(modp, 16);
        BigInteger g = BigInteger.valueOf(2);
        AlgorithmParameterSpec spec = new DHParameterSpec(p, g);
        
        KeyPairGenerator gen = KeyPairGenerator.getInstance("DiffieHellman");
        gen.initialize(spec);
        
    }
    
    @Test
    public void testWithMODP1024() throws GeneralSecurityException {
        
        testWith(modp1024);
        
    }
    
    @Test
    public void testWithMODP1536() throws GeneralSecurityException {
        
        testWith(modp1536);
        
    }
    
}

MODP1024 というのは RFC2409 The Internet Key Exchange (IKE) において "Second Oakley Group" と呼ばれていた 1024 ビットの素数で, MODP1536 というのは RFC3526 More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE) において "1536-bit MODP Group" と呼ばれていた 1536 ビットの素数です.

テストを実行してみると, testWithMODP1024 は成功しますが, testWithMODP1536 は失敗します. 失敗するのは, KeyPairGenerator インスタンスの initialize メソッドが, 次のような例外を投げるからです.

java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
    at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
    at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:658)
    at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:400)
    at tt4cs.rd.crypto.dh.DiffieHellmanParameterSpecTest.testWith(DiffieHellmanParameterSpecTest.java:42)
    at tt4cs.rd.crypto.dh.DiffieHellmanParameterSpecTest.testWithMODP1536(DiffieHellmanParameterSpecTest.java:56)
    :
    :

相変わらず, 1024 ビットを超える素数を用いることは, できていないようです.

これに関しては StackOverflow に Java 7 and Could not generate DH keypairJava: Why does SSL handshake give 'Could not generate DH keypair' exception? という投稿があります. コメント欄などを拝見しますと, バグ修正がおこなわれたみたいだよ, とか, Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files を適用すればいいよ, とか, いやいやその後のアップデートで再発するようになったよ, とか, そのポリシーファイルを適用しても効果がないよ, とか, いろいろあるようです.

今月に入って話題になっている OpenSSL 関連でネット上の情報をあさっていたら, たまたま Diffie-Hellman parameters - OpenSSLWiki (last updated on 8 Mar 2014) というページに Even worse, it appears that versions of Java prior to 1.7 don't support Diffie-Hellman parameters longer than 1024 bits! という記述を見つけました. それで, 思い出して, 最近ではもう 1024 ビットを超えるものも使えるようになったのかな?? と思って, ためしてみた次第でした.


追記 (19 Apr 2014): Java SE 8 (JDK 8u5) をはじめてダウンロードいたしまして, ためしてみましたところ, 上記のテストはパスしました. どうやら 2007 年頃から何度か関連チケットが上がっていたのにもかかわらず放置されつづけてきた本件も, JDK-7044060: Need to support NSA Suite B Cryptography algorithms でついに対応されたようですね. Java 6 はともかく, Java 7 にはバックポートしてくださってもいいのに.. という気はしなくもなかったり..

No comments:

Post a Comment