Skip to content

Instantly share code, notes, and snippets.

@teruteru128
Created July 12, 2016 09:54
Show Gist options
  • Save teruteru128/14c835d906d468154303fd3d0c8c6678 to your computer and use it in GitHub Desktop.
Save teruteru128/14c835d906d468154303fd3d0c8c6678 to your computer and use it in GitHub Desktop.
JavaでRSA鍵ペアを生成してみた@鍵ペア検証コード付き ref: http://qiita.com/teruteru128/items/b02078b115f3fdd3e1ac
素数生成完了
p : 11986036157968132346520837773856659201839110728802035511508317831681007979436002145500826499755663463491872944597086946814559027949874736415090464605880137
q : 9937658523438649360213691713305392768344928118607991280259811429812816516088395721590675912116362768528361503738754901598727081542350764090985811794454401
n : 119113134387475851867985689657000237177931905808165300526766493837814859856182158624264860506081520590229037346555991460737484576589634306133175864861578710606314396664765864609431629037347673593139937885276064477678386183356481130329007362710327345476281951711747292607172340202378498591050053012312318132937
n bit length : 1024
--------------------------------------------------------------
d : 7637111718512802379560795702255443438388541864990930204517643577009903430362656675452964643583846522119450309447003618078625969922786263551453453532330647570751911798130055257188134949112601213437337415154759051002112119038305133224325974939586200458322929216589258225550317239149829329203948856756075599873
4418EBA57209FED2C9B852673EF6D42F320066EC1B0175B2AF4B3E103F3B2719684CF39811D8BA6E2F8A455DD621079B7C0ACBB7ADCA368806BED51097822CCF05F72D8E9F001737EF3FE9993CCC62E4C1F87585CF95FF4639579150254DD2D4C995DD8A84848035DA7C3364EFAF922903CC96191E6E32763E13852CDA965BBE
テストてすとテストてすとテストてすとテストてすと
true
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
/**
* RSA鍵ペア生成
*/
public class Main {
/**
* */
private static final String CIPHER_ALGORITHM = "RSA";
/**
* */
private static final String CIPHER_MODE = CIPHER_ALGORITHM + "/ECB/PKCS1PADDING";
public static void main(String[] args) throws Exception {
/** 平文 */
String plainText = "テストてすとテストてすとテストてすとテストてすと";
/** 素数生成源 */
SecureRandom rnd = SecureRandom.getInstanceStrong();
/** セキュリティパラメータ(nのビット長) */
int nBitLength = 1 << 10;
/** pのビット長 */
int pBitLength = (nBitLength >> 1) + (nBitLength & 0x01);
/** qのビット長 */
int qBitLength = nBitLength >> 1;
/**
* 素数確実度 数値が大きいほど素数である確率が高くなる (代わりに実行時間が長くなる)
*/
int certainty = 100;
/** 素数q */
BigInteger p = null;
/** 素数q */
BigInteger q = null;
/** */
BigInteger n = null;
/** Φ(n) 1からnまでの自然数のうち n と互いに素なものの個数 */
BigInteger phiN = null;
/** 公開指数 決め打ち */
BigInteger publicExponent = BigInteger.valueOf(65537L);
/** 非公開指数 */
BigInteger d = null;
/* 素数p生成 */
p = new BigInteger(pBitLength, certainty, rnd);
do {
do {
/* 素数q生成 */
q = new BigInteger(qBitLength, certainty, rnd);
} while (p.equals(q));
/* qがpと等しい場合は再生成 */
/* p < q ならばpとqを入れ替える */
if (p.compareTo(q) < 0) {
BigInteger tmp = q;
q = p;
p = tmp;
}
n = p.multiply(q);
} while (n.bitLength() != nBitLength);
/* nのビット長がセキュリティパラメータに達しない場合素数を再生成 */
System.out.println("素数生成完了");
System.out.printf("p : %d%n", p);
System.out.printf("q : %d%n", q);
System.out.printf("n : %d%n", n);
System.out.printf("n bit length : %d%n", n.bitLength());
System.out.println("--------------------------------------------------------------");
/* Φ(n)=(p-1)(q-1) */
phiN = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
/* (d * publicExponent) ≡ 1 mod Φ(n) を満たす dを求める */
d = publicExponent.modInverse(phiN);
System.out.printf("d : %d%n", d);
/* ここまでで鍵ペア生成完了 以下暗号化テスト */
RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(n, d);
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, publicExponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = factory.generatePrivate(privateKeySpec);
PublicKey publicKey = factory.generatePublic(publicKeySpec);
byte[] cipher = encryptionTest(plainText.getBytes(), publicKey);
System.out.println(DatatypeConverter.printHexBinary(cipher));
byte[] decryptedText = decryptionTest(cipher, privateKey);
String restoredText = new String(decryptedText);
System.out.println(restoredText);
System.out.println(plainText.equals(restoredText));
}
/* 暗号化テスト */
static byte[] encryptionTest(byte[] plainText, PublicKey key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(plainText, 0, plainText.length);
}
/* 復号テスト */
static byte[] decryptionTest(byte[] cipherText, PrivateKey key) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText, 0, cipherText.length);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment