HOME
  Security
   Software
    Hardware
  
FPGA
  CPU
   Android
    Raspberry Pi
  
nLite
  Xcode
   etc.
    ALL
  
English Translate 中文翻訳
LINK
BACK
 

[NEW] 2020/01/11

Java言語で RSA暗号処理する方法、OpenSSLとの連携方法、Androidにも対応 Java言語で RSA暗号処理する方法、OpenSSLとの連携方法、Androidにも対応

(Java言語で公開鍵暗号方式の RSA暗号処理と OpenSSLと連携する方法を解説)

Tags: [Windows], [無人インストール]





● Microsoft Visual Studio 2013の C# .NETで RSA暗号処理する方法、OpenSSLとの連携方法

[NEW] 2020/01/11
Visual Studio 2013の .NET C#で RSA暗号処理する方法、OpenSSLとの連携方法
Visual Studio 2013の .NET C#で RSA暗号処理する方法、OpenSSLとの連携方法

  C# .NETで公開鍵暗号方式の RSA暗号処理と OpenSSLと連携する方法を解説


● Windowsで OpenSSLを使用して RSA暗号の暗号化、復号化をコマンドラインで実行する方法

[NEW] 2020/01/11
OpenSSLコマンドを使って RSA暗号処理する方法
OpenSSLコマンドを使って RSA暗号処理する方法

  OpenSSLコマンドで公開鍵暗号方式の RSA暗号処理する方法を解説


● Java言語で RSA暗号処理する方法、OpenSSLとの連携方法、Androidにも対応

 Android Java言語を使用して RSA暗号処理を試してみます。
 2020年になり、情報セキュリティの関係で今後ますます暗号化の需要が高まると思います。

 ※ Android以外の普通の Java環境でも実行できます。

 と言う訳で RSA暗号処理を実装できる様になります。


● RSA公開鍵暗号方式とは?

 RSAは公開鍵暗号方式で「公開鍵」「秘密鍵」の2種類のペアの鍵を用います。暗号と復号の鍵が異なるので「非対称暗号方式」とも言います。

 「公開鍵」=公開しても良い鍵
 「秘密鍵」=秘密にする鍵

 暗号と復号の鍵が同じものは「対称暗号方式」と言います。

 RSA暗号の鍵のビット長は現在は 2048bit以上が推奨されています。
 1024bit長の鍵は現在では既に「解読」されます。
 (現在のコンピュータの処理能力で短時間で演算処理して「秘密鍵」を求める事ができる)

 2048bit長の鍵の推奨される利用期間は 2030年末までとされています。
 (少なくとも暗号アルゴリズムの安全性が確保されると見込まれる期間)
 (現在のコンピュータの進化では 2050年頃には 2048bit長の RSA鍵が危殆化すると予想されています)

 現在が 2020年で、2030年までは 10年しかないのと、昨今のコンピュータの進化速度から 2048bit長でも不安があります。

 このぶんだと先を見越して 3072bit位を使用しておくのが「安全」と思います。
 ただし、ビット長が増加すると暗号化・復号化の処理の負荷が増加します。
 また、効率的な演算手法が「発見」された場合、そもそも RSA暗号方式そのものが「無力」になる可能性もあります。

● 各種暗号、ハッシュ関数の 2030年問題の一覧表

 2031年からは Security Strength 128以上が必須となる。
 (Security Strength 128未満は古いシステム用に「使用だけ」は許可 Legacy use)

NIST Special Publication 800-57 Recommendation for Key Management
Page 52 Table 2: Comparable strengths
Page 54 Table 3: Hash functions that can be used to provide the targeted security strengths
Page 55 Table 4: Security-strength time frames
 より引用して合成して作成

暗号強度公開鍵暗号
RSA暗号方式
鍵ビット長
公開鍵暗号
ECDSA暗号方式
(楕円曲線暗号)
鍵ビット長
共通鍵暗号
AES暗号方式
鍵ビット長
SHAハッシュ関数HMAC 暗号ハッシュ関数2030年末まで2031年以降
80以下
(112未満)
10241602TDEASHA-1--×
Legacy use
×
Legacy use
11220482243TDEASHA-224、SHA-512/224--×
Legacy use
1283072256AES-128SHA-256、SHA-512/256SHA-1
1927680384AES-192SHA-384SHA-224、SHA-512/224
25615360512AES-256SHA-512SHA-256、SHA-512/256

● EMVCoの資料
EMV SWG NH90 Notice Bulletin No. 23 July 2019 EMVCo Annual RSA Key Lengths Assessment
 より引用
RSA暗号方式
鍵ビット長
利用期限特定用途での延長
1408-bit2024年末まで2025年末まで
1984-bit2029年末まで--

● CRYPTREC Report 2016
CRYPTREC Report 2016
CRYPTREC Report 2016の公開 平成29年6月30日

 付録 A.3 予測図の更新(素因数分解問題及び楕円曲線上の離散対数問題の困難性)より引用

・CRYPTREC Report 2016 付録 A.3 予測図の更新(素因数分解問題及び楕円曲線上の離散対数問題の困難性)
CRYPTREC Report 2016 付録 A.3 予測図の更新(素因数分解問題及び楕円曲線上の離散対数問題の困難性)




● 暗号用語

 平文 = 元の文
 暗号文 = 暗号化した文
 暗号化 = 平文を暗号化して暗号文にする事
 復号化 = 暗号文を解読して平文に戻す事


● RSA公開鍵暗号方式の基本的な使い方

 その1:「送信者」が「受信者」だけに「メッセージ」を届ける場合
 ・「受信者」は「公開鍵」「秘密鍵」のペアの RSA鍵を生成する
 ・「送信者」は「受信者」から「公開鍵」を受け取る
 ・「送信者」はその「公開鍵」を使って「メッセージ」を暗号化する
 ・「送信者」は「暗号化メッセージ」を「受信者」に送信する
 ・「受信者」は「暗号化メッセージ」を「自分の秘密鍵」で復号化する
 ・「受信者」は「復号化メッセージ」を読む

 その2:「送信者」が自分である事を「受信者」に「認証・証明」したい場合
 ・「送信者」は「公開鍵」「秘密鍵」のペアの RSA鍵を生成する
 ・「送信者」は自分の「秘密鍵」を使って「メッセージ」を暗号化する
 ・「送信者」は「暗号化メッセージ」を「受信者」に送信する
 ・「受信者」は「暗号化メッセージ」を送信者の「公開鍵」で復号化する
 ・正常に復号化できれば「送信者」本人が送信した「メッセージ」である事が「認証・証明」できる

使い方目的暗号化復号化補足
その1メッセージの秘匿送信「受信者」の「公開鍵」「受信者」の「秘密鍵」受信者以外は暗号化メッセージを解読できない
その2自分である事の認証・証明「送信者」の「秘密鍵」「送信者」の「公開鍵」送信者以外は暗号化メッセージを作れない


● RSA公開鍵暗号方式の基本的な暗号強度の考え

 ある素数pとq、p*q=nの3個の数値がある場合に、
 ・p*qを演算してnを求めるのは簡単
 ・nの値から素数のpとqを求めるのは困難(pとqは素数である事)

 RSA暗号の暗号解読の難易度は、素数同士の積を求める事は(掛け算するだけだから)簡単であるが、逆に素数同士の積の値から素因数分解を求めるのが難しいと言う一方向性の数学的性質を利用しています。

 この場合、
 ・pとqが秘密鍵
 ・nが公開鍵
 になります。

RSA暗号 - Wikipedia

 面白記事
世界最小のRSA鍵ペアは何bitか
続・世界最小のRSA鍵ペアは何bitか

●楕円曲線暗号 Elliptic Curve Cryptography ECC

 楕円曲線を利用した暗号方式の総称で、RSAと同様の「公開鍵暗号」も実装できる。
 楕円曲線上の離散対数問題 (EC-DLP) の困難性を安全性の根拠とする暗号。
 楕円曲線暗号で有名なものとして ECDSAや ECDH等がある。

 RSA暗号などと比べた場合に同レベルの安全性をより短い鍵で実現でき、処理速度も速いのが利点。

楕円曲線暗号


● 公開鍵暗号は「ゴルゴ13」のデューク・トウゴウも関係しています。「最終暗号」

 ゴルゴ13 「最終暗号」

 数学者の佐久シゲルが解読不可能な暗号方式(最終暗号)を開発し、一般に公開しようとするのをアメリカの NSA(国家安全保障局)が妨害すると言うお話。

 なぜ妨害するかと言うと「解読不可能な暗号方式」で通信を行なわれると NSAが傍受・盗聴して通信内容を監視する事ができなくなるから。

 ゴルゴ13 デューク・トウゴウは佐久シゲルの学会での講演を聞き、その内容の意味(最終暗号の理論)を理解し、その最終暗号の開発が無事に完成する様に、また、NSAからの妨害工作から佐久シゲルを守るべくボディガードと支援を申し出る事にした。。。

 なお、既に各方面からツッコミが入っていますが「最終暗号」作中の「平方根を求める事は難しくても、~」の部分は誤りで、平方根を求めるのは「開平法」で手計算でも(頑張れば)できます。

 佐久シゲルのモデル 小平邦彦
小平邦彦
 小平次元、小平消滅定理、小平・スペンサー理論等に名を残している。

 NSA(アメリカ国家安全保障局)による市販ソフトウェアに仕込まれたバックドア(裏口)
NSA's Backdoor Key from Lotus-Notes
 "1984" O=MiniTruth CN=Big Brother


ゴルゴ13 (Volume108) 最終暗号 (SPコミックスコンパクト) (日本語) コミック - 2007/9/28
ASIN: 4845830612

ゴルゴ13 (129) (SPコミックス) (日本語) コミック - 2003/7/5
ASIN: 4845801299

ゴルゴ13 THE LAST CODE〜最終暗号〜 (My first big) (日本語) ムック - 2015/8/7
ASIN: 4091198481

暗号解読(上) (新潮文庫) (日本語) 文庫 - 2007/6/28
ASIN: 410215972X


● Java言語で RSA暗号の鍵を扱う場合の参考資料

jmeter_oauth_plugin/jmeter/src/main/java/org/apache/jmeter/protocol/oauth/sampler/PrivateKeyReader.java


● Java言語で RSA暗号処理する方法、OpenSSLとの連携方法のサンプルプログラム

 Java言語で RSA暗号化処理のサンプルプログラム

● Java言語のサンプルプログラムのコンパイル方法と実行方法
javac -encoding UTF-8 Sample.java
java -classpath . Sample

Sample.java
Javaの内部で RSA鍵ファイルを生成して
rsaTest1 秘密鍵で暗号化して、公開鍵で復号化する
rsaTest2 公開鍵で暗号化して、秘密鍵で復号化する

外部の DER形式の鍵ファイルを Javaで読み込んで
rsaTest3 公開鍵で暗号化して、秘密鍵で復号化する
rsaTest4 秘密鍵で暗号化して、公開鍵で復号化する

import java.io.IOException;

import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class Sample {

    public static void main(String[] args) throws Exception {
// Javaの内部で RSA鍵ファイルを生成して
// rsaTest1 秘密鍵で暗号化して、公開鍵で復号化する
// rsaTest2 公開鍵で暗号化して、秘密鍵で復号化する
        rsaTest1();
        rsaTest2();

// 外部の DER形式の鍵ファイルを Javaで読み込んで
// rsaTest3 公開鍵で暗号化して、秘密鍵で復号化する
// rsaTest4 秘密鍵で暗号化して、公開鍵で復号化する
        rsaTest3();
        rsaTest4();
    }

    // https://stackoverflow.com/questions/11410770/load-rsa-public-key-from-file
    // Load RSA public key from file in JAVA
    // How do I load my RSA Public Key from a file in JAVA ?
 /*
Generate a 2048-bit RSA private key
$ openssl genrsa -out private_key.pem 2048

Convert private Key to PKCS#8 format (so Java can read it)
$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -out private_key.der -nocrypt

Output public key portion in DER format (so Java can read it)
$ openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der
 */
    public static PublicKey getPublicKey(String filename)
            throws Exception {

        byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

        X509EncodedKeySpec spec =
                new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
    }

    public static PrivateKey getPrivateKey(String filename)
            throws Exception {

        byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

        PKCS8EncodedKeySpec spec =
                new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePrivate(spec);
    }

    public static void rsaTest1() {
        try {
            // 元のテキスト
            String plainText = "rsaTest1 秘密鍵で暗号化して、公開鍵で復号化する";

            System.out.println("");
            System.out.println("========");
            System.out.println(plainText);

            int keySize = 1024; // 1024 bit
            String transformation = "RSA/ECB/PKCS1Padding"; // PKCS #1 padding
            // ECB or NONE // RSAでは Modesパラメータは使用しない
            // PKCS1Padding or OAEPPadding // OAEPの方がセキュリティが高い
            // java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/NONE/PKCS1Padding
            // java.security.InvalidKeyException: OAEP cannot be used to sign or verify signatures

            // RSA用の「秘密鍵」「公開鍵」の生成
            String algorithm = "RSA";
            KeyPairGenerator kg = KeyPairGenerator.getInstance(algorithm);
            kg.initialize(keySize);
            KeyPair keyPair = kg.generateKeyPair();

            KeyFactory factoty = KeyFactory.getInstance(algorithm);
            // 「秘密鍵」
            RSAPrivateKeySpec privateKeySpec = factoty.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
            PrivateKey privateKey = factoty.generatePrivate(privateKeySpec);
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;

            // 「公開鍵」
            RSAPublicKeySpec publicKeySpec = factoty.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
            PublicKey publicKey = factoty.generatePublic(publicKeySpec);
            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

            // 162 bytes (1024 bit)
            byte[] publicKeyBytes = publicKey.getEncoded();
            System.out.println("publicKey.getEncoded: " + bytesToStr(publicKeyBytes));

            printRSAKeyInfo(rsaPublicKey, rsaPrivateKey);

            // 「秘密鍵」で暗号化する
            Cipher cipherEnc = Cipher.getInstance(transformation);
            cipherEnc.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] encryptedData = cipherEnc.doFinal(plainText.getBytes());

            // 「公開鍵」で復号化する
            Cipher cipherDec = Cipher.getInstance(transformation);
            cipherDec.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] decryptedData = cipherDec.doFinal(encryptedData);

            String decryptedText = new String(decryptedData, "UTF-8");

            // Windowsのコンソールで実行する場合は Shift-JISに変換する
            decryptedText = new String(decryptedData, "Shift_JIS");

            // 復号化した文字列を表示する
            System.out.println("decryptedText: " + decryptedText);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void rsaTest2() {
        try {
            // 元のテキスト
            String plainText = "rsaTest2 公開鍵で暗号化して、秘密鍵で復号化する";

            System.out.println("");
            System.out.println("========");
            System.out.println(plainText);

            int keySize = 1024; // 1024 bit
            String transformation = "RSA/ECB/PKCS1Padding"; // PKCS #1 padding
            // ECB or NONE // RSAでは Modesパラメータは使用しない
            // PKCS1Padding or OAEPPadding // OAEPの方がセキュリティが高い
            // java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/NONE/PKCS1Padding
            // java.security.InvalidKeyException: OAEP cannot be used to sign or verify signatures

            // RSA用の「秘密鍵」「公開鍵」の生成
            String algorithm = "RSA";
            KeyPairGenerator kg = KeyPairGenerator.getInstance(algorithm);
            kg.initialize(keySize);
            KeyPair keyPair = kg.generateKeyPair();

            KeyFactory factoty = KeyFactory.getInstance(algorithm);
            // 「秘密鍵」
            RSAPrivateKeySpec privateKeySpec = factoty.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);
            PrivateKey privateKey = factoty.generatePrivate(privateKeySpec);
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;

            // 「公開鍵」
            RSAPublicKeySpec publicKeySpec = factoty.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
            PublicKey publicKey = factoty.generatePublic(publicKeySpec);
            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

            printRSAKeyInfo(rsaPublicKey, rsaPrivateKey);

            // 「公開鍵」で暗号化する
            Cipher cipherEnc = Cipher.getInstance(transformation);
            cipherEnc.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedData = cipherEnc.doFinal(plainText.getBytes());

            // 「秘密鍵」で復号化する
            Cipher cipherDec = Cipher.getInstance(transformation);
            cipherDec.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedData = cipherDec.doFinal(encryptedData);

            String decryptedText = new String(decryptedData, "UTF-8");

            // Windowsのコンソールで実行する場合は Shift-JISに変換する
            decryptedText = new String(decryptedData, "Shift_JIS");

            // 復号化した文字列を表示する
            System.out.println("decryptedText: " + decryptedText);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void rsaTest3() {
        try {
            // 元のテキスト
            String plainText = "rsaTest3 公開鍵で暗号化して、秘密鍵で復号化する";

            System.out.println("");
            System.out.println("========");
            System.out.println(plainText);

            String transformation = "RSA/ECB/PKCS1Padding"; // PKCS #1 padding

            // 「秘密鍵」
            PrivateKey privateKey = getPrivateKey(".\\private_key.der");
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;

            // 「公開鍵」
            PublicKey publicKey = getPublicKey(".\\public_key.der");
            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

            // 294 bytes (2048 bit)
            byte[] publicKeyBytes = publicKey.getEncoded();
            System.out.println("publicKey.getEncoded: " + bytesToStr(publicKeyBytes));

            printRSAKeyInfo(rsaPublicKey, rsaPrivateKey);

            // 「公開鍵」で暗号化する
            Cipher cipherEnc = Cipher.getInstance(transformation);
            cipherEnc.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedData = cipherEnc.doFinal(plainText.getBytes());

            // 「秘密鍵」で復号化する
            Cipher cipherDec = Cipher.getInstance(transformation);
            cipherDec.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedData = cipherDec.doFinal(encryptedData);

            String decryptedText = new String(decryptedData, "UTF-8");

            // Windowsのコンソールで実行する場合は Shift-JISに変換する
            decryptedText = new String(decryptedData, "Shift_JIS");

            // 復号化した文字列を表示する
            System.out.println("decryptedText: " + decryptedText);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void rsaTest4() {
        try {
            // 元のテキスト
            String plainText = "rsaTest4 秘密鍵で暗号化して、公開鍵で復号化する";

            System.out.println("");
            System.out.println("========");
            System.out.println(plainText);

            String transformation = "RSA/ECB/PKCS1Padding"; // PKCS #1 padding

            // 「秘密鍵」
            PrivateKey privateKey = getPrivateKey(".\\private_key.der");
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;

            // 「公開鍵」
            PublicKey publicKey = getPublicKey(".\\public_key.der");
            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

            printRSAKeyInfo(rsaPublicKey, rsaPrivateKey);

            // 「秘密鍵」で暗号化する privateKey
            Cipher cipherEnc = Cipher.getInstance(transformation);
            cipherEnc.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] encryptedData = cipherEnc.doFinal(plainText.getBytes());

            // 「公開鍵」で復号化する publicKey
            Cipher cipherDec = Cipher.getInstance(transformation);
            cipherDec.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] decryptedData = cipherDec.doFinal(encryptedData);

            String decryptedText = new String(decryptedData, "UTF-8");

            // Windowsのコンソールで実行する場合は Shift-JISに変換する
            decryptedText = new String(decryptedData, "Shift_JIS");

            // 復号化した文字列を表示する
            System.out.println("decryptedText: " + decryptedText);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String bytesToStr(byte[] bytes)
    {
        StringBuilder str = new StringBuilder();
        for (byte aByte : bytes) str.append(String.format("%02X", aByte));

        return str.toString();
    }

    /**
     * Find a factor of n by following the algorithm outlined in Handbook of Applied Cryptography,
     * section 8.2.2(i). See http://cacr.uwaterloo.ca/hac/about/chap8.pdf .
     *
     */
    private static BigInteger findFactor(BigInteger e, BigInteger d, BigInteger n) {
        BigInteger edMinus1 = e.multiply(d).subtract(BigInteger.ONE);
        int s = edMinus1.getLowestSetBit();
        BigInteger t = edMinus1.shiftRight(s);

        for (int aInt = 2; true; ++aInt) {
            BigInteger aPow = BigInteger.valueOf(aInt).modPow(t, n);
            for (int i = 1; i <= s; ++i) {
                if (aPow.equals(BigInteger.ONE)) {
                    break;
                }
                if (aPow.equals(n.subtract(BigInteger.ONE))) {
                    break;
                }
                BigInteger aPowSquared = aPow.multiply(aPow).mod(n);
                if (aPowSquared.equals(BigInteger.ONE)) {
                    return aPow.subtract(BigInteger.ONE).gcd(n);
                }
                aPow = aPowSquared;
            }
        }

    }

    // Restore RSA private key by modulus, public and private exponents using Java Security
    // https://stackoverflow.com/questions/46837740/restore-rsa-private-key-by-modulus-public-and-private-exponents-using-java-secu
    // How to get a RSAPrivateCrtKey from a RSAPrivateKey?
    // https://stackoverflow.com/questions/43136036/how-to-get-a-rsaprivatecrtkey-from-a-rsaprivatekey
    public static void printRSAKeyInfo(RSAPublicKey rsaPub, RSAPrivateKey rsaPriv) {
        BigInteger e = rsaPub.getPublicExponent();
        BigInteger d = rsaPriv.getPrivateExponent();
        BigInteger n = rsaPub.getModulus();
        BigInteger p = findFactor(e, d, n);
        BigInteger q = n.divide(p);
        if (p.compareTo(q) > 0) {
            BigInteger t = p;
            p = q;
            q = t;
        }
        BigInteger exp1 = d.mod(p.subtract(BigInteger.ONE));
        BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
        BigInteger coeff = q.modInverse(p);

        System.out.println("---");
        System.out.println("Modulus   : " + n.toString(16));
        System.out.println("Public Ex : " + e.toString(16));
        System.out.println("---");
        System.out.println("Private Ex: " + d.toString(16));
        System.out.println("prime1    : " + p.toString(16));
        System.out.println("prime2    : " + q.toString(16));
        System.out.println("exp1      : " + exp1.toString(16));
        System.out.println("exp2      : " + exp2.toString(16));
        System.out.println("coeff     : " + coeff.toString(16));
    }

    public static RSAPrivateCrtKey createCrtKey(RSAPublicKey rsaPub, RSAPrivateKey rsaPriv) throws NoSuchAlgorithmException, InvalidKeySpecException {

        BigInteger e = rsaPub.getPublicExponent();
        BigInteger d = rsaPriv.getPrivateExponent();
        BigInteger n = rsaPub.getModulus();
        BigInteger p = findFactor(e, d, n);
        BigInteger q = n.divide(p);
        if (p.compareTo(q) > 0) {
            BigInteger t = p;
            p = q;
            q = t;
        }
        BigInteger exp1 = d.mod(p.subtract(BigInteger.ONE));
        BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
        BigInteger coeff = q.modInverse(p);

        // RSAPrivateCrtKey
        // 中国剰余定理 (CRT) の情報の値を使った、RSA 非公開鍵 (PKCS#1 標準の定義による) のインタフェース
        RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, exp1, exp2, coeff);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return (RSAPrivateCrtKey) kf.generatePrivate(keySpec);
    }
}


●実行結果
> java -classpath . Sample

========
rsaTest1 秘密鍵で暗号化して、公開鍵で復号化する
publicKey.getEncoded: 30819F300D06092A864886F70D010101050003818D003081890281810087331563A29F30DB935C8E48125383D967BF770252675818F55E975C293EC08224B080FB2B61EF4AFCE409590CCD2A3BE757E22E50BECBF532165E984FAED7DD29C16D1FE9DEE36DF5F9633246A8EAB09C2CD60E015CF540C6F267512E155264BE2F70A475E86E6D1A7E2464A284D80DF20C12B6B050E75688EBB9C6FE940C230203010001
---
Modulus   : 87331563a29f30db935c8e48125383d967bf770252675818f55e975c293ec08224b080fb2b61ef4afce409590ccd2a3be757e22e50becbf532165e984faed7dd29c16d1fe9dee36df5f9633246a8eab09c2cd60e015cf540c6f267512e155264be2f70a475e86e6d1a7e2464a284d80df20c12b6b050e75688ebb9c6fe940c23
Public Ex : 10001
---
Private Ex: 15d158924b9c04f66a4175748c008e3677579e8cf15f5c082b10a8bc66ab89c576c6450a4365fa87cf67bd5a71866a5a606afe451b22af27527de9a60ab5dc7fc664f7d7d840c6ae6419cb457aa88ee7bbdc15e360fcdaee85f6386cf6c6fb6cac2b5739308046a6459439b0224e1a63eb82532dd1a0a36882a1abcd9ce7d701
prime1    : 911ec972ae2a4108e75757fb1d4a8be85e60bab48854d6d88eac6f0508deff3b5634eecc9bec8e2303b81ad0479b6b9421af91d21cf29d8f34f2497741c40fb9
prime2    : ee7fd364085fd7dc782a62c2d49964f8c794ae888e53bd4f0632a4f3dcb16e2f081f9ae8516d911f94008947c4af68f0f500bf3e4fa12af60b4de80084e910bb
exp1      : 629c4dfcfc763fed01ee6b1d7b00ede2ff46b177fd6fd0f224b8ed53b97c7668e6a25f666fc9a5a80b5dedf27bc613aafbdce6b4a4f103b98d1bda6a0c296319
exp2      : 70bbd72e178f46379e4d5ab5814ca89fb7a71e00ca55e6cbedc00e9c7e9b17dbff59011e032f6943a5efc2f43b9236667f48c51d2d029f8e01b5e78e27450b75
coeff     : dc97de0c9b159cb4e9e7eaecdf9a40ddd53ce6fd85ac9f3432480149addb23c75c119210508e50b0b466110d6fab24907d09e3f7f8d39f0a15376e93fb9b750
decryptedText: rsaTest1 秘密鍵で暗号化して、公開鍵で復号化する

========
rsaTest2 公開鍵で暗号化して、秘密鍵で復号化する
---
Modulus   : b343c9fc73330c5081391961490d159e93c3768eadb5140aba2bf4a8d176e81b6d6af7cbec67c2b1ef0b4673f95a7b9e792ba3442cc9194e1eac770ae470f940cd555fbc04e1912f54c93e7bf2948e146e7e3f067b504a276c8d834a60c2c03104826564fdb7d968648ae85ae2a7e53a0c123c3640a68c3b4f6c1c6c8a215c49
Public Ex : 10001
---
Private Ex: cd0a2c6de415ef6fe55e39f95c64eae5867d7b8d9682177a6d96f9305ee572766ca07ced7268fbf82942ec429a633421fed63ad82fa194a015d58e139756e0bfa2b2c9c14e3120311f5ad3afaa30da0605ae1fd35a112784b5702f0357eec7d9055faab9e644e68d60c923689cc5a1b91840c93f48ed4e5a5000b3c1024c481
prime1    : c6df00264d5aa65e7936f541735e0fecd896b05488472eb513b07fb950e9efb486a5d197f949ed77d16224480ff3d4a76171e728e42c2b79f370c58e7104d871
prime2    : e6c2f0898f234f3db501f702a8d942223b4b0ae475b998d4c4c3f8f436daba4659b699b965b27443d32d8f6467563fadd82a14aee08182e17ea463ebd8ea6d59
exp1      : a7f257bc010397109da96e01b21e33b0bf50b2e510999cb64b4478f8d57e5a72c86b6ccfbd35539826798d4e563a82d24016e332c34f12005138617e63afc5e1
exp2      : a5bb03be07cb3831fd39f80934f3340819c57f812cfbaac3c4bd6aa31a7264adf9e8a6e6fc1efa596be5a0c25f65163ee8acf045d87fab5bfff458bf1dfedfa1
coeff     : 92676e54a992617b78605a5aa95ef4433436026b39b0bb6d08be470655ad3f286aed88d2b37e9d6338af14f4589d3bdd994a2432745e45a97f26e8eb2f64b791
decryptedText: rsaTest2 公開鍵で暗号化して、秘密鍵で復号化する

========
rsaTest3 公開鍵で暗号化して、秘密鍵で復号化する
publicKey.getEncoded: 30820122300D06092A864886F70D01010105000382010F003082010A0282010100D5C4389D67E487EF20BA5DAEA599CE8A94DA120939F1FB9BF42EB36E9E118635888F984B1B194D974B18A13C1A935EA273A15395A9CBAC2B20319DA480C0E0F7AF1C98090BED0C467B2A670AAF8C332815334B7B4BCC0B6AE8C214CD7E860976E53EFA91DA5AB8AC0B020CC4C70371F912C25D521BF0D6145EB4FC5D66207E5048C83A9074B6624810C734146ED29E6B6EB9BE9A06B9F8FD01BC735F9AFAFDEA3BF7C98EDA0148C8D8862A796F62D357373845E97FD0051177EBCDB2B5C47287842AE01933F3D43FF414A437A36A88B4B9A0774CD56AB82BCF6F810E7FDCEF55192D78FDB66B7E85547C4454AB5B53503BCB1E8CDBC1A88BEAB2D7FC2B89352F0203010001
---
Modulus   : d5c4389d67e487ef20ba5daea599ce8a94da120939f1fb9bf42eb36e9e118635888f984b1b194d974b18a13c1a935ea273a15395a9cbac2b20319da480c0e0f7af1c98090bed0c467b2a670aaf8c332815334b7b4bcc0b6ae8c214cd7e860976e53efa91da5ab8ac0b020cc4c70371f912c25d521bf0d6145eb4fc5d66207e5048c83a9074b6624810c734146ed29e6b6eb9be9a06b9f8fd01bc735f9afafdea3bf7c98eda0148c8d8862a796f62d357373845e97fd0051177ebcdb2b5c47287842ae01933f3d43ff414a437a36a88b4b9a0774cd56ab82bcf6f810e7fdcef55192d78fdb66b7e85547c4454ab5b53503bcb1e8cdbc1a88beab2d7fc2b89352f
Public Ex : 10001
---
Private Ex: 847bb4fed109d0b982561e8383fcbc062554b5c2e417b5f1a4b760db58b9d1acd1f2f4d6ef7792200719bfabc968b6490652e0c3abd51fe22674b997df782ab536e108d4ea80429057fb229b7bcaef559336143cd8f01fcf656c0b8a8434bc1ee4db505e1eaf052f132f750c6baf15eee11276d5d19d4480a16597d6a6d9d28dfb331d8a84ab0cd2bd3536d31a273754a7f8fc317bea23ab39c22a6f139a74273fbdabeacfa8e0b37e9c066cb62542b133fd6379efda3610dcacae640c5b03c3da8b2b17da3137620ef7b2082ee61a1bfa6094f1e5a3010dcb21350aa652050411f9af3721f891c2336cd0c54a79b07574b8abef8b505d1a700f6b7053410031
prime1    : e168ce97f549c47a97411c2571c74aa68724ff7ddb295b6d94c1c3c053d612670f26eff69451592dbba4fe6c540d061f4f35a4b644c3c1314cac6f2dcf3702c5b4e8b1599059bd21e1732ae583282048186c20423dbdaa529fe85b86480aac1ff7e6193d194de6eb703a852ea483215da166b7011824a12a6ce335a5c9fb48f7
prime2    : f2c6ea3fcb213357fd9e250a9508a53ef99583b0d6e6ec0be587b0cb0003960ad2fb98fb62d6edd1e36855c0863fd8017d76e00e41a8998c8386f31093fdf25b98716fd4b9f37dd9de4196f847c370386a16e432067abf4c513f6eb88ba4e2febb1310e97e0d13060bd1bb813eccfb9de61e8a52c5d6bf3f2bfa079fec80df89
exp1      : 56e92747160f944f4444998aa27d19fe6d7b497b886640d75695035a03b935ad40fd5d66b0b750f03e3a96d2c3f1a59baad9df215c10324c44e8f39131255fcf453ab72ef66673733dcf3f09f1712649460962c2c7b57a97930a6f47ae3d5732984dc30b78d73da327c998926c62171a57e217cbb738605fd04e26e03ea9c1ef
exp2      : a089ead2fe76d8e5e19ed6edb5797f1432a4aced9e5e1b4f0e9bf8cb7419eaf903653e575597bcb1a34816147671f75b9ce4a3eaa97e5cf32ef268fed86dfffa93c6c7658b05397e7d5b3002c429b7a68678d6b341d79f724ef3bc3aaa950149e2d90bc0eb0aa83ec248114eb901818d7b634ca2c99264ead820c133fe8785c9
coeff     : 2d791e0ee4f16cbd86bd5b392cb0a3a0cbd40dfc90bdfb68ff1068968bb98c23f7f4b9a9c0aa614f674c9e6d16ec2226e77876cdcb45ac79becabf22c1c4c1ddee03b9918ba469683131cadf34bc7f5fffaddf29be8662ef894b70db7c157d3a8247eadd963003df89ade84fe543dfbe90d0d54d3cda32ca6692edb3e4cc8a32
decryptedText: rsaTest3 公開鍵で暗号化して、秘密鍵で復号化する

========
rsaTest4 秘密鍵で暗号化して、公開鍵で復号化する
---
Modulus   : d5c4389d67e487ef20ba5daea599ce8a94da120939f1fb9bf42eb36e9e118635888f984b1b194d974b18a13c1a935ea273a15395a9cbac2b20319da480c0e0f7af1c98090bed0c467b2a670aaf8c332815334b7b4bcc0b6ae8c214cd7e860976e53efa91da5ab8ac0b020cc4c70371f912c25d521bf0d6145eb4fc5d66207e5048c83a9074b6624810c734146ed29e6b6eb9be9a06b9f8fd01bc735f9afafdea3bf7c98eda0148c8d8862a796f62d357373845e97fd0051177ebcdb2b5c47287842ae01933f3d43ff414a437a36a88b4b9a0774cd56ab82bcf6f810e7fdcef55192d78fdb66b7e85547c4454ab5b53503bcb1e8cdbc1a88beab2d7fc2b89352f
Public Ex : 10001
---
Private Ex: 847bb4fed109d0b982561e8383fcbc062554b5c2e417b5f1a4b760db58b9d1acd1f2f4d6ef7792200719bfabc968b6490652e0c3abd51fe22674b997df782ab536e108d4ea80429057fb229b7bcaef559336143cd8f01fcf656c0b8a8434bc1ee4db505e1eaf052f132f750c6baf15eee11276d5d19d4480a16597d6a6d9d28dfb331d8a84ab0cd2bd3536d31a273754a7f8fc317bea23ab39c22a6f139a74273fbdabeacfa8e0b37e9c066cb62542b133fd6379efda3610dcacae640c5b03c3da8b2b17da3137620ef7b2082ee61a1bfa6094f1e5a3010dcb21350aa652050411f9af3721f891c2336cd0c54a79b07574b8abef8b505d1a700f6b7053410031
prime1    : e168ce97f549c47a97411c2571c74aa68724ff7ddb295b6d94c1c3c053d612670f26eff69451592dbba4fe6c540d061f4f35a4b644c3c1314cac6f2dcf3702c5b4e8b1599059bd21e1732ae583282048186c20423dbdaa529fe85b86480aac1ff7e6193d194de6eb703a852ea483215da166b7011824a12a6ce335a5c9fb48f7
prime2    : f2c6ea3fcb213357fd9e250a9508a53ef99583b0d6e6ec0be587b0cb0003960ad2fb98fb62d6edd1e36855c0863fd8017d76e00e41a8998c8386f31093fdf25b98716fd4b9f37dd9de4196f847c370386a16e432067abf4c513f6eb88ba4e2febb1310e97e0d13060bd1bb813eccfb9de61e8a52c5d6bf3f2bfa079fec80df89
exp1      : 56e92747160f944f4444998aa27d19fe6d7b497b886640d75695035a03b935ad40fd5d66b0b750f03e3a96d2c3f1a59baad9df215c10324c44e8f39131255fcf453ab72ef66673733dcf3f09f1712649460962c2c7b57a97930a6f47ae3d5732984dc30b78d73da327c998926c62171a57e217cbb738605fd04e26e03ea9c1ef
exp2      : a089ead2fe76d8e5e19ed6edb5797f1432a4aced9e5e1b4f0e9bf8cb7419eaf903653e575597bcb1a34816147671f75b9ce4a3eaa97e5cf32ef268fed86dfffa93c6c7658b05397e7d5b3002c429b7a68678d6b341d79f724ef3bc3aaa950149e2d90bc0eb0aa83ec248114eb901818d7b634ca2c99264ead820c133fe8785c9
coeff     : 2d791e0ee4f16cbd86bd5b392cb0a3a0cbd40dfc90bdfb68ff1068968bb98c23f7f4b9a9c0aa614f674c9e6d16ec2226e77876cdcb45ac79becabf22c1c4c1ddee03b9918ba469683131cadf34bc7f5fffaddf29be8662ef894b70db7c157d3a8247eadd963003df89ade84fe543dfbe90d0d54d3cda32ca6692edb3e4cc8a32
decryptedText: rsaTest4 秘密鍵で暗号化して、公開鍵で復号化する



Tags: [Windows], [無人インストール]

●関連するコンテンツ(この記事を読んだ人は、次の記事も読んでいます)

OpenSSLコマンドを使って RSA暗号処理する方法
OpenSSLコマンドを使って RSA暗号処理する方法

  OpenSSLコマンドで公開鍵暗号方式の RSA暗号処理する方法を解説

Visual Studio 2013の .NET C#で RSA暗号処理する方法、OpenSSLとの連携方法
Visual Studio 2013の .NET C#で RSA暗号処理する方法、OpenSSLとの連携方法

  C# .NETで公開鍵暗号方式の RSA暗号処理と OpenSSLと連携する方法を解説

PHP言語で RSA暗号処理する方法、OpenSSLとの連携方法
PHP言語で RSA暗号処理する方法、OpenSSLとの連携方法

  PHP言語で 公開鍵暗号方式の RSA暗号処理と OpenSSLと連携する方法を解説

GO言語で RSA暗号処理する方法、OpenSSLとの連携方法
GO言語で RSA暗号処理する方法、OpenSSLとの連携方法

  GO言語で 公開鍵暗号方式の RSA暗号処理と OpenSSLと連携する方法を解説

Visual Studio 2013の C# .NETで Hash計算処理をする方法のサンプルプログラム
Visual Studio 2013の C# .NETで Hash計算処理をする方法のサンプルプログラム

  HashAlgorithm.TransformBlockを使用すると巨大ファイル等でハッシュ計算の進行状況の進捗を取得できます

Visual Studio 2013の .NET C#で UTF-8対応 QRコード生成・読取アプリを作成する方法、ZXing.Net QR Codeライブラリを使用
Visual Studio 2013の .NET C#で UTF-8対応 QRコード生成・読取アプリを作成する方法、ZXing.Net QR Codeライブラリを使用

  .NETで UTF-8対応 QRコード作成・解読アプリを作成、ILMergeで dllを exeに合体する方法

C# .NETで ZIPファイル解凍ツール UnZipをソースリスト 1行で自作する方法、Windows .NET専用
C# .NETで ZIPファイル解凍ツール UnZipをソースリスト 1行で自作する方法、Windows .NET専用

  Visual Studio 2013の C# .NET 4.5で ZipFile.ExtractToDirectoryを使い、UnZip解凍ツールを作成

Visual Studio 2013に Windows 10 SDK + UwpDesktopで UWPの機能を素の Windowsアプリから使用
Visual Studio 2013に Windows 10 SDK + UwpDesktopで UWPの機能を素の Windowsアプリから使用

  VS2013に Win 10 SDKをインストールして Uwp Desktopで UWPの機能を従来の Windowsアプリで動かす

Visual Studio 2013の C# .NETで 日本語対応の OCR文字認識アプリを自作する方法
Visual Studio 2013の C# .NETで 日本語対応の OCR文字認識アプリを自作する方法

  オフライン環境で動作可能な 世界各国語対応の OCR文字認識アプリを C# .NETで作成、MS製 OCRライブラリを使用

Visual Studio 2013の C#で日本語対応の手書き文字認識アプリを自作する方法
Visual Studio 2013の C#で日本語対応の手書き文字認識アプリを自作する方法

  オフライン環境で動作する世界各国語対応の手書き文字認識アプリを作成、MS製 手書き認識ライブラリを使用

Open XML SDKを使用して Officeのファイルを C#で自在に操る方法
Open XML SDKを使用して Officeのファイルを C#で自在に操る方法

  Microsoft Officeのファイルをプログラムで生成したり直接中身の読み取りができます

Visual Studioの各バージョンと開発できる .NET Frameworkの各バージョンのまとめ
Visual Studioの各バージョンと開発できる .NET Frameworkの各バージョンのまとめ

  .Microsoft.NET Framework Developer Packの各バージョンのダウンロードまとめ。言語パック等

Windows 10対応 Microsoft Speech使用の音声認識アプリ
Windows 10対応 Microsoft Speech使用の音声認識アプリ

  SpeechRecognizeApp 音声認識エンジンを使用してマイク入力の音声を認識します

Windows 10の音声合成エンジンを使用して入力した文字列を喋る & Waveファイル書き出し
Windows 10の音声合成エンジンを使用して入力した文字列を喋る & Waveファイル書き出し

  SpeechApp Windows 10用 Speech 音声合成 Text-to-Speech TTSのアプリ

Visual Studioの C#や MFC C++用のサンプルアプリのリンク集
Visual Studioの C#や MFC C++用のサンプルアプリのリンク集

  Visual Studioの C#や MFC C++でアプリを作る時の参考資料として

Windowsの Input Method Manager IMEや TSF Text Services Frameworkの公式情報源のまとめ
Windowsの Input Method Manager IMEや TSF Text Services Frameworkの公式情報源のまとめ

  Windowsで IME Input Method Manager関連のアプリを作成する時の情報 ImeTrayもこの辺を必死に読んだ

Visual Studioの C#で開発した .Netアプリの難読化をする方法
Visual Studioの C#で開発した .Netアプリの難読化をする方法

  C#で開発した .Netアプリの難読化は必須事項です、素の状態では簡単に内部を解析されます

Visual Studioの C#で開発した .Netアプリを逆コンパイルして、中身の実装を覗き見る方法
Visual Studioの C#で開発した .Netアプリを逆コンパイルして、中身の実装を覗き見る方法

  C#で開発した .Netアプリは比較的簡単に元のソースコードに戻せます

Visual Studio 2019 Professional v16.4を無人インストールする方法、完全自動でインストール
Visual Studio 2019 Professional v16.4を無人インストールする方法、完全自動でインストール

  VS2019 v16.4を完全オフラインインストール&コンポーネント選択の事前設定で自動インストールする

Visual Studio 2013 Professionalを無人インストールする方法、完全自動でインストール
Visual Studio 2013 Professionalを無人インストールする方法、完全自動でインストール

  VS2013を Update 5適用済みとコンポーネント選択の事前設定でインストール時の手間を省く



[HOME] | [BACK]
リンクフリー(連絡不要、ただしトップページ以外は Web構成の変更で移動する場合があります)
Copyright (c) 2020 FREE WING,Y.Sakamoto
Powered by 猫屋敷工房 & HTML Generator

http://www.neko.ne.jp/~freewing/software/rsa_encrypt_decrypt_java_language/