対称暗号化 (DES、AES) の Java 実装のクイック スタート例

対称暗号化では、暗号化と復号化に同じパスワードが使用されます。対称暗号化は実装が簡単ですが、セキュリティは非対称暗号化よりも弱いです。一般的に使用される対称暗号化アルゴリズムには、DES、AES、PDE などがあります。対称暗号化の関連概念については、次を参照してください。対称暗号化
、非対称暗号化の詳細な分析

この記事では、Java での DES および AES の暗号化と復号化について紹介します。PDE アルゴリズムの暗号化と復号化の実装については、「Java は
対称暗号化と復号化に PBE アルゴリズムを使用する」および「例」を参照してください。

DES 暗号化と復号化

Java 言語では、DES アルゴリズムは暗号化と復号化にキーを使用し、暗号仕様 (DESKeySpec) とキー ファクトリ (SecretKeyFactory) を使用してキーを生成します。暗号化と復号化の操作は Cipher クラスを通じて実行され、暗号化アルゴリズムとパディング モードとして「DES/ECB/PKCS5Padding」が使用されます。

DES 暗号化のサンプル コード:

	/**
	 * DES 对称加密
	 */
	@Test
	public void desEncrypt() throws Exception {
		String plainText = "需要加密的内容";
		String secretKey = "this is password";
		DESKeySpec desKeySpec = new DESKeySpec(secretKey.getBytes(StandardCharsets.UTF_8));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(desKeySpec);

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, key);

		byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
		String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
		System.out.println("DES加密后的内容=" + encryptedText);
	}

DES 復号化のサンプル コード:

	
	@Test
	public void desDecrypt() throws Exception {
		String encryptedText = "HAyFHQXRKmihGtxFsrZlAJwla4FE3aqS";
		String secretKey = "this is password";
		DESKeySpec desKeySpec = new DESKeySpec(secretKey.getBytes(StandardCharsets.UTF_8));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(desKeySpec);

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		cipher.init(Cipher.DECRYPT_MODE, key);

		byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
		String plainText = new String(decryptedBytes, StandardCharsets.UTF_8);
		System.out.println("DES解密的内容=" + plainText);
	}

なぜ直接 DES ではなく DES/ECB/PKCS5Padding がここにあるのですか?

DES/ECB/PKCS5Padding は、データの暗号化と復号化によく使用される暗号化アルゴリズムとモードの仕様です。

具体的には:

  • DES (Data Encryption Standard) は、暗号化操作と復号化操作に同じキー (通常は 56 ビット長) を使用する対称暗号化アルゴリズムです。
  • ECB (Electronic Codebook) は、入力データをブロックに分割し、各ブロックが独立して暗号化演算を実行する暗号化モードです。
  • PKCS5Padding は、データ ブロックの長さが不十分な場合に特定のパディング方法を使用して埋め込み、各データ ブロックの長さが指定された長さに達するようにするパディング モードです。

他の暗号化アルゴリズムおよびモードと比較すると、DES/ECB/PKCS5Padding には次のような利点と欠点があります。

アドバンテージ:

  • 動作速度は比較的高速で、大規模なデータ ストリームの暗号化および復号化に適しています。

  • 実装は比較的単純で、さまざまなプログラミング言語やプラットフォームで実装できます。

  • 暗号化されたデータのサイズは増加しません。

欠点:

  • ECB モードにはランダム性と反復率がなく、隣接するデータ ブロックが同じ暗号文を生成する可能性があるため、攻撃に対して脆弱です。

  • キーの長さは短く、セキュリティは比較的低く、ブルート フォース クラッキングや暗号解析攻撃に対して脆弱です。

同じデータを同じキーで暗号化すると、暗号文は常に同じになるため、リプレイ攻撃やパスワード攻撃が容易になります。

したがって、暗号化パフォーマンス要件が高く、セキュリティ要件が比較的低いシナリオでは、暗号化および復号化操作に DES/ECB/PKCS5Padding を使用することを選択できます。高度なセキュリティ要件があるシナリオの場合は、AES、RSA、CBC、GCM など、より安全で信頼性の高い暗号化アルゴリズムとモードの使用を検討する必要があります。

AES暗号化と復号化

AES の暗号化と復号化は DES と非常に似ています。コードを見てください。

AES 暗号化コードの例:

	@Test
	public void encryptAES() throws Exception {
		String plainText = "需要加密的内容";
		String secretKey = "this is password";
		SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
        
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        String encryptedText =  Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("AES加密后的内容=" + encryptedText);
	}

AES 復号化コードの例:

	@Test
	public void decryptAES() throws Exception {
		String encryptedText = "oL2b5xULTtAmfi4ujnpw/jPamo0nTNCgRC9Bo+SBz7k=";
		String secretKey = "this is password";
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
		String plainText = new String(decryptedBytes, StandardCharsets.UTF_8);
		System.out.println("AES解密的内容=" + plainText);
	}

AES (Advanced Encryption Standard) は、暗号化操作と復号化操作に同じキーを使用します。この例では、キー文字列を使用して AES キー仕様 (SecretKeySpec) が構築され、暗号化と復号化の操作は Cipher クラスを通じて実行され、暗号化アルゴリズムとパディング モードとして「AES/ECB/PKCS5Padding」が使用されます。

AES はブロック暗号アルゴリズムであり、DES などのブロック暗号とは異なり、AES-128、AES-192、AES-256 などのさまざまなキー長をサポートしていることに注意してください

実際のアプリケーションでは、セキュリティを確保するために、キーは十分な長さである必要があり、同時にキーの安全な生成、保管、送信を保証する必要があります。

Java 8 が javax.crypto.spec.SecretKeySpec を見つけられない問題の解決方法

Java 11 および Java 17 バージョンでは、上記の例は正常に動作しますが、Java 8 では、javax.crypto.spec.SecretKeySpec が見つからないというメッセージが表示されます。Eclipse ベースの開発では、SecretKeySpec はインポートされますが、見つかりません このクラス:

The import javax.crypto.spec.SecretKeySpec cannot be resolved

ここで、jce 拡張パッケージをダウンロードする必要があります。ダウンロード アドレス:
https://www.oracle.com/java/technologies/javase-jce8-downloads.html

ダウンロード後解凍し、
ここに画像の説明を挿入

local_policy.jar と US_export_policy.jar を JRE の security ディレクトリに配置します。たとえばC:\Program Files\Java\jdk1.8.0_361\jre\lib\security\policy\unlimited、このディレクトリ内の同じ名前のファイルを上書きします。
ここに画像の説明を挿入

次に、これら 2 つのファイルを Eclipse プロジェクトにインポートします。

オンラインコード



おすすめ

転載: blog.csdn.net/oscar999/article/details/132254062