楕円曲線暗号の署名検証をJavaで実装してみる
暗号理論の中で、RSAと同じ公開鍵暗号に属する楕円曲線暗号(Elliptic Curve Cryptography: ECC)ですが、RSAちゃんよりできる子と言われ続けて早15年くらい?
このまま秘密兵器のまま終わるのかと思いきや、ようやっと使われ始める兆しがあったりなかったりなので、Javaでの実装方法について調べてみました。
Javaでは、JDK 7以上で楕円曲線暗号のネイティブ・プロバイダが追加されたようです。
サンプルコード
楕円曲線DSA(Elliptic Curve Digital Signature Algorithm: ECDSA)での、署名検証サンプルコードです。
鍵ペアの生成、署名の作成、署名の検証を順に実施しています。
実際に使う場合には、署名作成する人と署名検証をする人は別の人になりますが、サンプルでは同じメソッド内でやってます。
package com.example;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import javax.xml.bind.DatatypeConverter;
public class ECDSAExample {
/**
* 楕円曲線DSA 署名検証サンプル
*/
public static void main(String[] args) throws Exception {
/*
* 楕円曲線暗号 鍵ペア生成
*/
// 鍵ペア生成器
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); // Elliptic Curve
// 乱数生成器
SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
// 鍵サイズと乱数生成器を指定して鍵ペア生成器を初期化
int keySize = 256;
keyGen.initialize(keySize, randomGen);
// 鍵ペア生成
KeyPair keyPair = keyGen.generateKeyPair();
// 秘密鍵
PrivateKey privateKey = keyPair.getPrivate();
// 公開鍵
PublicKey publicKey = keyPair.getPublic();
/*
* 署名生成
*/
String originalText = "This is string to sign";
// 署名生成アルゴリズムを指定する
Signature dsa = Signature.getInstance("SHA1withECDSA");
// 初期化
dsa.initSign(privateKey);
// 署名生成
dsa.update(originalText.getBytes("UTF-8"));
// 生成した署名を取り出す
byte[] signature = dsa.sign();
System.out.println("Signature: " + DatatypeConverter.printHexBinary(signature));
/*
* 署名検証
*/
// 初期化
dsa.initVerify(publicKey);
// 署名検証する対象をセットする
dsa.update(originalText.getBytes("UTF-8"));
// 署名検証
boolean verifyResult = dsa.verify(signature);
System.out.println("Verify: " + verifyResult);
}
}
KeyPairGeneratorアルゴリズム
鍵ペアジェネレータの引数には、他に以下のものを指定することが出来ます。
アルゴリズム名 | 説明 |
---|---|
DiffieHellman | Diffie-Hellman KeyAgreementアルゴリズムの鍵ペアを生成します。 注: key.getAlgorithm()は、「DiffieHellman」ではなく「DH」を返します。 |
DSA | デジタル署名アルゴリズムの鍵ペアを生成します。 |
RSA | RSAアルゴリズム(Signature/Cipher)の鍵ペアを生成します。 |
EC | Elliptic Curveアルゴリズムの鍵ペアを生成します。 |
SecureRandom乱数生成アルゴリズム
乱数生成ジェネレータの引数には、他に以下のものを指定することが出来ます。
アルゴリズム名 | 説明 |
---|---|
NativePRNG | 基盤となるネイティブOSから乱数を取得します。乱数生成のブロック性については何も表明されません。 |
NativePRNGBlocking | 基盤となるネイティブOSから乱数を取得し、必要に応じてブロック化します。たとえば、UNIX系システムの/dev/randomなど。 |
NativePRNGNonBlocking | 基盤となるネイティブOSから乱数を取得しますが、アプリケーションの速度低下を避けるためブロック化しません。たとえば、UNIX系システムの/dev/urandomなど。 |
PKCS11 | 基盤となるインストールおよび構成済みのPKCS11ライブラリから乱数を取得します。 |
SHA1PRNG | Sunプロバイダが提供する擬似乱数生成(PRNG)アルゴリズム。このアルゴリズムは、PRNGの基盤としてSHA-1を使用します。各操作につき値が1増加する64ビット・カウンタを使って鎖状につながった真にランダムなシード値から、SHA-1ハッシュを計算します。160ビットのSHA-1出力のうち、64ビットだけが使用されます。 |
Windows-PRNG | 基盤となるWindows OSから乱数を取得します。 |
Signatureアルゴリズム
署名アルゴリズムには、他に以下のものを指定することが出来ます。
アルゴリズム名 | 説明 |
---|---|
NONEwithRSA | RSA操作を行う前にダイジェスト・アルゴリズム(MD5/SHA1など)を使用しないRSA署名アルゴリズム。RSA署名アルゴリズムについては、PKCS#1を参照してください。 |
MD2withRSA MD5withRSA |
PKCS#1で定義された、RSA暗号を使用したMD2/MD5署名アルゴリズム。MD2/MD5ダイジェスト・アルゴリズムおよびRSAを使用してRSAデジタル署名を作成および検証します。 |
SHA1withRSA SHA224withRSA SHA256withRSA SHA384withRSA SHA512withRSA |
OSI Interoperability Workshopで定義された、SHA-*およびRSA暗号化アルゴリズムを使用した署名アルゴリズム。PKCS#1に記述されているパディング規則を使用します。 |
NONEwithDSA | FIPS PUB 186-2で定義されたデジタル署名アルゴリズム。このデータの長さは正確に20バイトである必要があります。このアルゴリズムは、rawDSAとも呼ばれています。 |
SHA1withDSA SHA224withDSA SHA256withDSA |
FIPS PUB 186-3で定義された、SHA-1、SHA-224またはSHA-256ダイジェスト・アルゴリズムを使用してデジタル署名を作成および検証するDSA署名アルゴリズム。 |
NONEwithECDSA SHA1withECDSA SHA224withECDSA SHA256withECDSA SHA384withECDSA SHA512withECDSA (ECDSA) |
ANSI X9.62で定義されたECDSA署名アルゴリズム。 注:「ECDSA」は「SHA1withECDSA」アルゴリズムのあいまいな名前であるため、使用しないでください。代わりに、正式な名前「SHA1withECDSA」を使用します。 |
<digest>with<encryption> | この形式を使用して、特定のメッセージ・ダイジェスト(MD2、MD5など)とアルゴリズム(RSA、DSAなど)を使用する署名アルゴリズムの名前を指定します。このセクションで紹介した明示的に定義されている標準名(MD2withRSAなど)も同じ形式で指定されています。 PKCS#1 v2.0で定義された新しい署名方式の場合は、<digest>with<encryption>の形式では不十分なため、<digest>with<encryption>and<mgf>の形式を使用して名前を指定できます。<mgf>は、MGF1などのマスク生成機能に置き換える必要があります。例: MD5withRSAandMGF1。 |
参考元
java - Tutorial of ECDSA algorithm to sign a string - Stack Overflow
https://stackoverflow.com/questions/11339788/tutorial-of-ecdsa-algorithm-to-sign-a-string
Java暗号化アーキテクチャ標準アルゴリズム名のドキュメント(JDK 8用) - #KeyPairGeneratorアルゴリズム
http://docs.oracle.com/javase/jp/8/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator
Java暗号化アーキテクチャ標準アルゴリズム名のドキュメント(JDK 8用) - #SecureRandom乱数生成アルゴリズム
http://docs.oracle.com/javase/jp/8/docs/technotes/guides/security/StandardNames.html#SecureRandom
Java暗号化アーキテクチャ標準アルゴリズム名のドキュメント(JDK 8用) - #Signatureアルゴリズム
http://docs.oracle.com/javase/jp/8/docs/technotes/guides/security/StandardNames.html#Signature
「Java 暗号化アーキテクチャ API 仕様 & リファレンス」の付録 A(PRNG アルゴリズムの標準的な名前)
https://docs.oracle.com/javase/jp/1.4/guide/security/CryptoSpec.html#AppA
Elliptical curve cryptography in java
http://rahulatjava.blogspot.jp/2014/02/elliptical-curve-cryptography-in-java.html
bc-java/ECIESTest.java at master · bcgit/bc-java
https://github.com/bcgit/bc-java/blob/master/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java
Encryption and Decryption of Data using Elliptic Curve Cryptography( ECC ) with Bouncy Castle C# Library
https://www.codeproject.com/Tips/1071190/Encryption-and-Decryption-of-Data-using-Elliptic-C
Author And Source
この問題について(楕円曲線暗号の署名検証をJavaで実装してみる), 我々は、より多くの情報をここで見つけました https://qiita.com/asksaito/items/39ee36e165e521af7716著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .