暗号 [java] 暗号化方式におけるデジタル署名に関する予備的研究

序文

  • keytool の使用に関する部分はまだ実現されていないので、最初に記録してください。

1 デジタル署名の概要

  • デジタル署名 (公開キー デジタル署名とも呼ばれます) は、メッセージの送信者のみが生成でき、他人が偽造することのできないデジタル文字列です。このデジタル文字列は、送信されたメッセージの信頼性を証明する有効な証拠でもあります。メッセージの送信者によって。
  • これは、紙に書かれた通常の物理署名に似たデジタル情報を認証する方法ですが、公開キー暗号化の分野の技術を使用して実装されています。
  • デジタル署名のセットは通常、2 つの相補的な操作 (1 つは署名用、もう 1 つは検証用) を定義します。
  • デジタル署名は、非対称鍵暗号技術とデジタル抽象化技術を応用したものです。

  • デジタル署名の意味は、ネットワーク上でデータを送信する際に、誰が送信したかを示すデジタル署名がデータに付加され、データが改ざんされていないことを証明することもできます。

2 基本原則

張三には仲の良い友人AとBがいると言われている。仕事上の理由により、Zhang San、A、B は電子メールを書くときに安全のために暗号化する必要があります。そこで、Zhang San 氏はデジタル署名について考えました。

  • ステップ 1: 暗号化には非対称暗号化が使用されます。Zhang San は 3 つの鍵と 2 つの公開鍵を持っており、それらを友人に渡しています。秘密鍵は自分用に保管してください。
  • ステップ 2: A または B が Zhang San に電子メールを書き込みます。A はまず公開キーを使用して電子メールを暗号化し、次に Zhang San は受信後に秘密キーを使用して電子メールを復号化します。
  • ステップ 3: Zhang San は A または B に電子メールを書きます。
    1. Zhang San 氏は電子メールを書き終えた後、まずハッシュ関数を使用して電子メールの概要を生成し、それを記事に添付してデジタル署名を完成させ、次に Zhang San 氏はそれを秘密キーで暗号化して電子メールを送信しました。
    2. A または B が電子メールを受信したら、まずデジタル署名を削除し、次に独自の公開キーを使用して電子メールを復号化します。このとき、取り出したデジタル署名の要約が張三のものと一致する場合は、張三が送信したものとみなし、レター自体にハッシュ関数を使用し、その結果を、以前に取得した要約と比較します。前のステップ。2 つが一致すれば、文字が改ざんされていないことが証明されます。
      ここに画像の説明を挿入

ここに画像の説明を挿入

3 つのデジタル証明書

ここに画像の説明を挿入

  • 署名を検証するには公開キーが必要です。公開鍵が偽造された場合、デジタル署名を検証することができなくなり、デジタル署名から相手の正当性を判断することができなくなります。ここで証明書が登場します。私たちは皆、北京語の証明書、CET-4 および CET-6 証明書などのさまざまな証明書を取得した経験があるかもしれませんが、最終的には、どのような機会でも証明書を提示して、実際に合格したことを証明できます。北京語検定試験に合格し、4級または6級に合格した。ここでの証明書についても同じことが当てはまります。
  • 証明書の生成
    ここに画像の説明を挿入

4 Webページの暗号化

「デジタル証明書」適用例:httpsプロトコル。このプロトコルは主に Web 暗号化に使用されます

  • まず、クライアントはサーバーに対して暗号化されたリクエストを送信します。
    ここに画像の説明を挿入
  • サーバーは独自の秘密キーを使用して Web ページを暗号化した後、それを独自のデジタル証明書とともにクライアントに送信します。
    ここに画像の説明を挿入
  • クライアント (ブラウザ) の「証明書マネージャー」には、「信頼されたルート証明機関」のリストがあります。クライアントは、このリストに従って、デジタル証明書のロックを解除するための公開鍵がリストにあるかどうかを確認します。
  • 電子証明書に記録されている URL が閲覧中の URL と一致しない場合、この証明書が不正に使用されている可能性があり、ブラウザから警告が表示されます。
    ここに画像の説明を挿入

5 つのエッジ Web サイト接続アイコン

  • Microsoft Edge で Web を閲覧すると、アクセスする Web サイトへの接続の安全性を示すアイコンがアドレス バーに表示されます。このアイコンは、Web サイトから情報を送受信しても安全かどうかを判断するのに役立ちます。接続は、サイトとの間で送受信される情報 (パスワード、アドレス、クレジット カードなど) が安全に送信され、攻撃者によって傍受できないかどうかを示します。接続はサイトの評判には影響しません。ただし、アドレスが既知のフィッシング サイトまたはマルウェア サイトである場合、Microsoft Defender SmartScreen はそのアドレスを識別して表示します。
  • アドレス バーの接続アイコンには 4 つの異なる状態があります。次の情報は、各ステータスの意味を説明し、ブラウジングに関して賢明な決定を下すためのヒントを提供します。
    • 安全な接続 (有効な証明書)
      ここに画像の説明を挿入
    • 完全なセキュリティなし (証明書証明書)
      ここに画像の説明を挿入
    • 期限切れのセキュリティ構成 (無効、期限切れ、自己署名)
      ここに画像の説明を挿入
    • 疑わしいまたは危険な Web サイト (フィッシングまたはマルウェア)
      ここに画像の説明を挿入

6 コードの実装

package com.atguigu.Signature;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class SignatureDemo {
    
    
    public static void main(String[] args) throws Exception {
    
    
        String a = "123";

        PublicKey publicKey = getPublicKey( "a.pub","RSA");
        PrivateKey privateKey = getPrivateKey("a.pri","RSA");

        String signaturedData = getSignature(a, "sha256withrsa", privateKey);

        boolean b = verifySignature(a, "sha256withrsa", publicKey, signaturedData);
        System.out.println(b);

    }

    /**
     * 读取公钥
     * @param publicPath 公钥路径
     * @param algorithm  算法
     * @return
     */
    public static PublicKey getPublicKey(String publicPath, String algorithm) throws Exception{
    
    
        String publicKeyString = FileUtils.readFileToString(new File(publicPath), Charset.defaultCharset());
        // 创建key的工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        // 创建公钥规则
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        return keyFactory.generatePublic(keySpec);
    }

    /**
     *  读取私钥
     * @param priPath 私钥的路径
     * @param algorithm 算法
     * @return 返回私钥的key对象
     */
    public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception{
    
    
        String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
        // 创建key的工厂
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        // 创建私钥key的规则
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        // 返回私钥对象
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 生成签名
     *
     * @param input      : 原文
     * @param algorithm  : 算法
     * @param privateKey : 私钥
     * @return : 签名
     * @throws Exception
     */
    private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception {
    
    
        // 获取签名对象
        Signature signature = Signature.getInstance(algorithm);
        // 初始化签名
        signature.initSign(privateKey);
        // 传入原文
        signature.update(input.getBytes());
        // 开始签名
        byte[] sign = signature.sign();
        // 对签名数据进行Base64编码
        return Base64.encodeBase64String(sign);
    }

    /**
     * 校验签名
     *
     * @param input          : 原文
     * @param algorithm      : 算法
     * @param publicKey      : 公钥
     * @param signaturedData : 签名
     * @return : 数据是否被篡改
     * @throws Exception
     */
    private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception {
    
    
        // 获取签名对象
        Signature signature = Signature.getInstance(algorithm);
        // 初始化签名
        signature.initVerify(publicKey);
        // 传入原文
        signature.update(input.getBytes());
        // 校验数据
        return signature.verify(Base64.decodeBase64(signaturedData));
    }
}

7 keytoolツールの使用

  • keytool ツールのパス:C:\Program Files\Java\jdk-19\bin
    ここに画像の説明を挿入

7.1 一般的なコマンド:

  1. キーペアの生成
    keytool -genkeypair
    keytool -genkeypair -alias lisi(后面部分是为证书指定别名,否则采用默认的名称为mykey)
    
  2. キーストア内の項目を表示します。
    keytool -list或keytool -list -v
    keytool -exportcert -alias lisi -file lisi.cer
    
  3. 印刷可能な証明書を生成します。
    keytool -exportcert -alias lisi -file lisi.cer –rfc
    
  4. デジタル証明書ファイル内の証明書情報を表示します。
    keytool -printcert -file lisi.cer
    
    • lisi.cer を直接ダブルクリックすると、ウィンドウ システムの組み込みプログラムで lisi.cer が開きます。

7.2 秘密鍵と公開鍵の生成 [実際には失敗しました]

  1. キー証明書の生成 次のコマンドは、RSA アルゴリズムを使用してキー証明書を生成します。各証明書には公開キーと秘密キーが含まれています。
keytool -genkeypair -alias guigu -keyalg RSA -keypass guigugu -keystore guigu.jks -storepass guigugu
  • Keytool は Java によって提供される証明書管理ツールです。

    -alias:密钥的别名 
    -keyalg:使用的hash算法 
    -keypass:密钥的访问密码 
    -keystore:密钥库文件名,xc.keystore保存了生成的证书 
    -storepass:密钥库的访问密码 
    
  1. 証明書情報のクエリ
    keytool -list -keystore guigu.jks
    
  2. エイリアスの削除
    keytool -delete -alias guigu -keystore guigu.jsk
    

7.3 公開鍵のエクスポート

  • openssl は暗号化および復号化ツールキットであり、ここでは公開鍵情報をエクスポートするために使用されます。
  • opensslをインストールする
  1. Win64OpenSSL-1_1_0g.exe をデータ ディレクトリにインストールし、openssl のパス環境変数を次のように構成します。
    ここに画像の説明を挿入
  • Cmd は、guigu.jks ファイルが存在するディレクトリに入り、次のコマンドを実行します (次のコマンドは Windows で実行されます。中国語に変更されます。英語に変更してください)。
keytool -list -rfc --keystore guigu.jks | openssl x509 -inform pem -pubkey
  • 次の段落は公開キーです
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvFsEiaLvij9C1Mz+oyAm
t47whAaRkRu/8kePM+X8760UGU0RMwGti6Z9y3LQ0RvK6I0brXmbGB/RsN38PVnh
cP8ZfxGUH26kX0RK+tlrxcrG+HkPYOH4XPAL8Q1lu1n9x3tLcIPxq8ZZtuIyKYEm
oLKyMsvTviG5flTpDprT25unWgE4md1kthRWXOnfWHATVY7Y/r4obiOL1mS5bEa/
iNKotQNnvIAKtjBM4RlIDWMa6dmz+lHtLtqDD2LF1qwoiSIHI75LQZ/CNYaHCfZS
xtOydpNKq8eb1/PGiLNolD4La2zf0/1dlcr5mkesV570NxRmU1tFm8Zd3MZlZmyv
9QIDAQAB
-----END PUBLIC KEY-----
  • 上記の公開鍵をテキストファイルの public.key にコピーし、1 行に結合して、認可認証を実装する必要があるプロジェクトに配置します。

おすすめ

転載: blog.csdn.net/yang2330648064/article/details/130537200