Opensslとkeytoolはrsa鍵と証明書開発ガイドを生成します


目次
 
一、RSAとは
二、der符号化とpem符号化
三、opensslコマンドrsa鍵の生成
四、RSA暗号化標準PKCS
五、鍵と証明書
六、jks証明書
一、RSAとは
RSAは公開鍵暗号アルゴリズムであり、その名前は3人の開発者、すなわちRon Rivest、Adi Shamir、Leonard Adlemanの姓の頭文字から構成されている.RSAは、公開鍵パスワードおよびデジタル署名に使用される.
二、der符号化とpem符号化
プログラムコードまたはopensslコマンドを使用して鍵ペアを生成すると、メモリにデータが生成され、ファイルにシーケンス化されます.データのシーケンス化には、特定の符号化フォーマットであるDERが必要である.DERはdistinguished encode ruleの略で、ASNです.1通常のテキストではなくバイナリである符号化規格の符号化方式.DER符号化バイナリ出力のファイルはバイナリファイルになります.PEMは、暗号学key、証明書、および他のデータを格納および送信するためのファイルフォーマットの事実基準である.ASNを多く使用する.1の暗号化規格(例えばX.509とPKCS)はいずれもDER符号化を用いているが、DER符号化の内容はバイナリであり、メールとの転送には適していない(初期のEmailでは添付ファイルを送信できない)ため、PEMを用いてバイナリコンテンツをASCII符号に変換する.ファイルコンテンツのフォーマットは以下のようになる.
-----BEGIN label-----
BASE64Encoded
-----END label-----

Labelは、RSA Private Keyがpem形式で符号化したファイルの内容など、コンテンツがどのようなタイプなのかを区別するために使用されます.
-----BEGIN RSA PRIVATE KEY-----
BASE64Encoded
-----END RSA PRIVATE KEY-----

PEMは実際にはDER符号化されたファイルのバイナリコンテンツをbase 64で符号化し、-----BEGIN label-----のようなヘッダと-----END label-----のような末尾を加え、真ん中がDERファイルのBase 64符号化である.
三、opensslコマンドrsa鍵の生成
1.opensslを使用してrsa秘密鍵を生成する
openssl genrsa -out private.pem 2028

Opensslで生成された秘密鍵ファイルのデフォルトでpem符号化フォーマットの場合、次のコマンドを使用してder符号化フォーマットに変換できます.
openssl rsa -in private.pem -outform der -out private.der

2.rsa秘密鍵からrsa公開鍵を得る
openssl rsa -in private.pem -pubout -out public.pem

四、RSA暗号化標準PKCS
1.PKCSのフルネームはPublic-Key Cryptography Standardsであり、RSA実験室と他のセキュリティシステム開発者が公開鍵暗号の発展を促進するために制定した一連の標準である.PKCSは現在15の標準を発表しています.次に、私たちがよく出会う標準フォーマットを3つ紹介します.
1)PKCS#1:RSA暗号化規格.PKCS#1は、RSA公開鍵関数の基本フォーマット基準、特にデジタル署名を定義する.署名対象データと署名自体のフォーマットを含むデジタル署名の計算方法を定義します.PSA公開/秘密鍵の構文も定義されています.Opensslコマンドを使用して生成した鍵はpkcs 1形式です.
2)PKCS#8:秘密鍵情報構文基準.PKCS#8は、秘密鍵情報構文および暗号化秘密鍵構文を定義し、秘密鍵暗号化はPKCS#5規格を使用する.JAvaではこの基準が使用されています.
3)PKCS#12:個人情報交換文法基準.PKCS#12は、個人情報(秘密鍵、証明書、各種秘密および拡張フィールドを含む)のフォーマットを定義する.PKCS#12は、証明書および対応する秘密鍵の送信を容易にし、ユーザは、異なるデバイス間で個人情報を移動することができる.ブラウザで使用されるこの基準である.
2.javaコードPKCS#8形式のrsaキーファイルを読み込む
public static PrivateKey getPemPrivateKey(String filename) throws Exception {
        byte[] keyBytes = readFile(filename);
        String temp = new String(keyBytes);

        //   lable  
        String privKeyPEM = temp.replace("-----BEGIN PRIVATE KEY-----", "");
        privKeyPEM = privKeyPEM.replace("-----END PRIVATE KEY-----", "");

        //    DER                
        BASE64Decoder b64 = new BASE64Decoder();
        byte[] decoded = b64.decodeBuffer(privKeyPEM);

        //   key   pcks#8
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        return kf.generatePrivate(spec);
}

上のコードは、ロードキーキーのフォーマットがpkcs#8であることを指定していますが、javaは他のpkcsフォーマットのキーを使用できますか?答えは不可ですが、少なくともサードパーティ拡張プラグインを使用しない場合は不可です.rsaキーファイルを読み込むときによく遭遇するエラーはjavaです.security.InvalidKeyException: IOException : Short read of DER length .その問題の原因はkeyのpkcsフォーマットが間違っており,keyのフォーマット変換操作が必要であることである.
3.openssl変換鍵pkcs形式
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
openssl rsa -in pkcs8.pem -pubout -out public_pkcs8.pem

五、鍵と証明書
1.証明書とは
公開鍵証明書(public key certificate)は、送信者の名前と認可を検証するためのデジタル署名ファイルである.この署名ファイルは、証明書所有者の名前を含む特殊なフォーマットのデータセグメントからなる(利用者またはシステムの名前かもしれない)、所有者の公開鍵、認証機関が認証に用いるデジタル署名などの情報.RSAアルゴリズムに基づいて通信を暗号化するAB双方において、Aはまず自分の公開鍵をBに送る必要があり、BはAにメッセージを送る際には、まずAの公開鍵でメッセージを暗号化してからAに伝える.しかし、この中には、BがAのアイデンティティを検証できないという問題があり、いずれのサードパーティCも、Aを装って自分の公開鍵をBに送信することができるからである.証明書は公開鍵keyのアイデンティティを説明します.証明書には公開鍵の内容に加えて、自分の身分を明らかにする情報も含まれています.
2. SHA
証明書に公開鍵および公開鍵の開示情報のみが含まれている場合、第三者攻撃者が証明書情報をブロックし、ファイルの内容を勝手に改ざんすることができるため、セキュリティ上の問題があります.ファイルの内容が破壊されていないことを保証する手段が必要です.まず、公開鍵の内容が証明書に含まれているため、証明書の内容を暗号化することはできません.私たちはウェブサイトで大きなファイルをダウンロードする時、いくつかのウェブサイトはこのファイルに対してmd 5演算を行った後に得た一連のhash値を与えて、私たちはダウンロードファイルが完成した後に、同様にmd 5アルゴリズムを使ってファイルに対して1つのhash値を生成して、hash値が等しいかどうかを比較することによってファイルの完全性を確定します.証明書検証も同様の手段を用いてhash関数を用いて証明書の情報要約を生成し、この要約はhash文字値の列である.次にrsa秘密鍵を用いて要約を暗号化し、暗号化された値を証明書ファイルに再格納し、証明書の一部として受信者に送信し、受信者は証明書の公開鍵を取り出し、公開鍵を用いて情報要約値を復号し、証明書の内容に対して同じhash関数を用いて新しい情報要約を得、2つの値が等しいかどうかを比較する.このプロセスは証明書のデジタル署名です.安全Hash関数(SHA)は最も広く使われているHash関数である.他の広く使われていたHash関数には安全上の危険性が発見されているため、2005年から現在までSHAは残されているHashアルゴリズムの標準かもしれない.
SHAは、アメリカ標準技術研究所(NIST)が設計し、1993年に発表した.このバージョンはSHA-0と呼ばれ、すぐにセキュリティ上の危険性が発見されたため、1995年にSHA-1が発表された.2002年、NISTはそれぞれSHA-256、SHA-384、SHA-512を発表し、これらのアルゴリズムを総称してSHA-2と呼ぶ.2008年にはSHA-224が追加された.SHA-1はあまり安全ではないため、現在SHA-2の各バージョンが主流となっている.
私たちがよく見かける名詞RSA 256は、実はRSA-SHA 256の略称で、RSA非対称暗号化を採用し、SHA 256を採用して証明書を生成するデジタル署名を指す.一方、RSA 1024、RSA 2048は、鍵keyを生成する長さを指す.
3.openssl自己署名証明書の生成
既存のRSA秘密鍵を使用して、自己署名証明書を生成します.
openssl req -new -x509 -days 365 -key private.pem -out mycert.crt

4.CA証明書
上記では、keyのソースを明らかにするために証明書を使用し、デジタル署名を使用して証明書の内容が改ざんされていないことを保証します.しかし証明書の正当性を証明することはできず、第三者攻撃者として同様の手段で自分の証明書を送信者と偽って送信者に送信することができる.証明書の出所を確保するために認証センターが必要です.CAです.CAは証明書の発行機関であり、公開鍵インフラストラクチャ(Public Key Infrastructure,PKI)の核心である.CAは証明書の発行、認証証明書の発行、発行された証明書の管理を担当する機関である.
CA証明書と自己署名証明書の違いは、CA機関が自分の秘密鍵を使って私たちが提出した証明書にデジタル署名を生成し、ユーザー側(ブラウザ側など)でこれらのCA機関の公開鍵を取得し、この公開鍵で証明書の合法性を検証し、証明書の中の公開鍵を取得することです.
六、jks証明書
1.jksとkeytool
Javaキーストア(JKS)は、セキュリティ証明書(ライセンス証明書または公開鍵証明書)および対応する秘密鍵(例えばSSL暗号化用)のリポジトリである.簡単に言えばjavaが開発した特許形式である証明書でもある.KeytoolはJavaデータ証明書の管理ツールであり、Keytoolは鍵(key)と証明書を(certificates)keystoreというファイルがkeystoreに存在します.
ポイント:java webプログラムを開発し、セキュリティ認証が必要な場合はjava keytoolツールを使用してjksファイルを生成し、公開鍵証明書をエクスポートします.opensslツールを使用して公開秘密鍵を生成する必要はありません.jksファイルにはこれらのデータが含まれているためです.
2.jksファイルの生成および公開鍵証明書のエクスポート
keytool -genkey -alias "myjks" -keyalg "RSA" -keystore "myjks.keystore" -keypass "123456" -storepass "123456" -validity 180

公開鍵証明書のエクスポート:
keytool -keystore myjks.keystore -export -alias myjks -file myjks.crt -rfc

3.javaプログラムはjksファイルを読み込みます:
public static RSAPrivateKey getPrivateKeyFromFile(String keystorePath, String alias) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(keystorePath);
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(fileInputStream, KEYSTORE_PWD.toCharArray());
        RSAPrivateKey privateKey = (RSAPrivateKey) ks.getKey(alias, KEY_PWD.toCharArray());
        return privateKey;
    }

4.javaプログラムjks公開鍵証明書の読み出し
 public static RSAPublicKey getPublicKeyFromFile(String filePath) throws IOException, CertificateException {
        String pemString = FileUtils.readFileToString(new File(filePath));
        CertificateFactory fact = CertificateFactory.getInstance("X.509");
        ByteArrayInputStream is = new ByteArrayInputStream(
                pemString.getBytes("UTF8"));

        X509Certificate cer = (X509Certificate) fact.generateCertificate(is);
        return (RSAPublicKey) cer.getPublicKey();
    }