2012-06-07 19 views
7

私はドキュメントに署名し、それをネットワーク経由でアプリケーションサーバーに送信する分散デジタル署名を開発しています。私はjavaでソケットプログラミングを使用しています。私は公開鍵をコード化するか圧縮する必要があると思います。つまり、xとyの値は何とか1つのバイナリデータとして表現され、パブリックレジストリやネットワークに保存されます。どのように楕円曲線の公開鍵を圧縮またはエンコードしてネットワーク上に置くのですか?

私は署名の検証は、あなたがuはつもりに持って検証者に、ネットワークを介してそれらを送信するときit.becauseを使用するために、それをデコードするように、公開鍵とドメインパラメータをエンコードする方法を知りたい
 // I have class like this 
      public class CryptoSystem{     

       EllipticCurve ec = new EllipticCurve(new P192()); 

       //------------------- 
       //-------------------- 

       public ECKeyPair generatekeyPair() 
       { 
        return ECKeyPair(ec); 

       } 


      }  
     // i don't think i have problem in the above 


    CryptoSystem crypto = new CryptoSystem(); 
    ECKeyPair keyPair = crypto.generateKeyPair(); 
    BigInteger prvKey = keyPair.getPrivateKey(); 
    ECPoint pubKey = keyPair.getPublicKey(); 
    // recommend me here to compress and send it the public key to a shared network. 

Bouncy Castle Providerを使用していません。 ECDSAアルゴリズムの実装全体が私のプロジェクトです

+0

あなたがメモリ内にそれらを表現するにはどうすればよい?彼らはただ、大きな整数だ、Security.addProvider(new BouncyCastleProvider())(あなたのJREに弾む城プロバイダを追加する必要があります。 – CodesInChaos

+0

でください、あなたはポイント圧縮を使用したいのですか?これは、x座標とy座標の符号のみをシリアル化して、y座標を復元するためにカーブ方程式を使用するテクニックです。 – CodesInChaos

+0

はい、圧縮に加えて、共有ネットワークレジストリの公開鍵で、2つ以上のアプリケーションサーバが署名を検証するために使用します –

答えて

9

楕円曲線の点は、ほとんどの場合、X9.62で指定されたエンコーディングを使用してエンコードされます。

ポイント圧縮を使用することはオプションです。ポイント圧縮を使用してエンコードするのは簡単ですが、圧縮ポイントをデコードするにはもう少し作業が必要です。余分なバイトを実際に保存する必要がなければ、気にしません。あなたがそれを必要とするかどうか教えてください。詳細を追加します。 X9.62エンコードされたポイントをポイント圧縮で最初のバイト(0x02または0x03)で認識できます。

ポイント圧縮を使用しないエンコーディングは、単純に0x04(圧縮しないことを示す)で始まります。次に、フィールドのバイトサイズまで左の両方のゼロ詰め、次いで、y座標、最初のx座標と次のとおり

int qLength = (q.bitLength()+7)/8; 
byte[] xArr = toUnsignedByteArray(x); 
byte[] yArr = toUnsignedByteArray(y); 
byte[] res = new byte[1+2*qLength]; 
res[0] = 0x04; 
System.arraycopy(xArr, 0, res, qLength - xArr.length, xArr.length); 
System.arraycopy(yArr, 0, res, 2* qLength - yArr.length, nLength); 

が、これはもちろん自明で復号を行います。

+0

ありがとう、私はurの答えを理解しています。遠隔地にある1つ以上のアプリケーションサーバーが公開鍵を使用して保存する必要がありますか? –

+0

ドメインパラメータ(q、a、b、G、n、h)はどのようにしてリモート署名検証アプリに渡されますか?Uサインとして動的に楕円曲線を選択しているからです。 p-192、p-224、....、p-512推奨楕円曲線のドメインパラメータ –

+0

@Clickmit:あなたは静的なドメインパラメータを持っていて、両端にハードコードされていると仮定します。サポートされているカーブのリストが少しだけあれば、使用しているカーブを指定する整数を前置するようなことをします。すべてのドメインパラメータをエンコードしたい場合は、そのための標準もあります(ECDomainParameters ASN.1構造を参照してください)が、そのためのASN.1 DERエンコーダを見つけるべきだと思います。このような構造のエンコーディングを手作業でコーディングすることは自明ではありません。 –

3

BCの実装ではX9.63エンコーディングが使用されているので、これらはむしろ標準化されたエンコーディングになります。あなたは、彼らは簡単なはずシリアライズ、弾むマニュアルを参照してください。

public static void showECKeyEncodings() { 

    try { 
     KeyPairGenerator kp = KeyPairGenerator.getInstance("ECDSA"); 
     ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable 
       .getParameterSpec("prime192v1"); 
     kp.initialize(ecSpec); 
     KeyPair keyPair = kp.generateKeyPair(); 

     PrivateKey privKey = keyPair.getPrivate(); 
     byte[] encodedPrivKey = privKey.getEncoded(); 
     System.out.println(toHex(encodedPrivKey)); 

     PublicKey pubKey = keyPair.getPublic(); 
     byte[] encodedPubKey = pubKey.getEncoded(); 
     System.out.println(toHex(encodedPubKey)); 

     KeyFactory kf = KeyFactory.getInstance("ECDSA"); 
     PublicKey pubKey2 = kf.generatePublic(new X509EncodedKeySpec(encodedPubKey)); 
     if (Arrays.equals(pubKey2.getEncoded(), encodedPubKey)) { 
      System.out.println("That worked for the public key"); 
     } 

     PrivateKey privKey2 = kf.generatePrivate(new PKCS8EncodedKeySpec(encodedPrivKey)); 
     if (Arrays.equals(privKey2.getEncoded(), encodedPrivKey)) { 
      System.out.println("That worked for the private key"); 
     } 

    } catch (GeneralSecurityException e) { 
     throw new IllegalStateException(e); 
    } 

} 
+0

私はBouncy CastleのECDSAの実装を再利用していません。私は自分で実装していますが、ネットワーク上で1バイト配列として送信するためにDomainパラメータのエンコーディングに問題があり、ベリファイア側でデコードする必要があります –

+1

その場合は、許可されたBouncy Castleの実装です。コピーしない場合は、ドメインパラメータの標準X9.62エンコーディングを参照するだけです。 BSI TR-03111には、(より単純な)ドメインパラメータを符号化する方法もあります。 –

+1

この例は、KeyPairGeneratorとKeyFactoryに "EC"を渡す必要があることを除いて、JDK 1.8でも動作するようです。 – kravietz

関連する問題