[[335623]] 暗号化アルゴリズムは、一般的に、可逆暗号化と不可逆暗号化に分けられます。可逆暗号化は、さらに対称暗号化と非対称暗号化に分けられます。 1. 不可逆暗号化 一般的な不可逆暗号化アルゴリズムには、MD5、HMAC、SHA1、SHA-224、SHA-256、SHA-384、SHA-512 などがあります。その中で、SHA-224、SHA-256、SHA-384、SHA-512 は、総称して SHA2 暗号化アルゴリズムと呼ばれます。SHA 暗号化アルゴリズムのセキュリティは MD5 よりも高く、SHA2 暗号化アルゴリズムは SHA1 よりも高くなっています。 SHA の後の数字は暗号化された文字列の長さを示します。SHA1 はデフォルトで 160 ビットの情報サマリーを生成します。 不可逆暗号化アルゴリズムの最大の特徴は鍵ですが、HMAC では鍵 [手動犬頭] が必要です。 これらの暗号化は元に戻せないため、最も一般的なシナリオはユーザー パスワードの暗号化です。検証プロセスでは、暗号化された 2 つの文字列が同じかどうかを比較して ID を確認します。インターネット上には、MD5 パスワードを解読できると主張する Web サイトも多数あります。原理は同じで、多数の文字列とそれに対応する MD5 暗号化文字列を格納する巨大なリソース ライブラリがあり、それらを入力した MD5 暗号化文字列と比較します。パスワードの複雑さが比較的低い場合は、検証される可能性が依然として高くなります。 1.1 MD5 MD5 メッセージ ダイジェスト アルゴリズム (英訳: MD5 Message-Digest Algorithm) は、広く使用されている暗号化ハッシュ関数であり、128 ビット (16 バイト) のハッシュ値を生成して、情報伝送の整合性と一貫性を確保できます。 MD5 アルゴリズムには次の特性があります。 1. 圧縮: データの長さに関係なく、計算されたMD5値の長さは同じになります。 2. 計算が簡単: MD5値は元のデータから簡単に計算できます。 3. 改ざん防止: 1バイトが変更されただけでも、計算されたMD5値は大きく異なります。 4. 衝突防止: データと MD5 値がわかっている場合、同じ MD5 値を持つ元のデータを見つける可能性は非常に低くなります。 - 公共 静的文字列md5(文字列テキスト) {
- メッセージダイジェスト messageDigest = null ;
- 試す {
- メッセージダイジェスト = MessageDigest.getInstance( "MD5" );
- } キャッチ (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- byte[] バイト = messageDigest.digest(text.getBytes());
- Hex.encodeHexString(bytes)を返します。
- }
1.2 SHAシリーズ セキュア ハッシュ アルゴリズム (SHA) は、暗号化ハッシュ関数のファミリであり、FIPS によって認定されたセキュア ハッシュ アルゴリズムです。デジタル メッセージに対応する固定長文字列 (メッセージ ダイジェストとも呼ばれる) を計算できるアルゴリズム。また、入力メッセージが異なる場合、異なる文字列に対応する可能性が高くなります。 2005 年 8 月 17 日の CRYPTO カンファレンスの最後に、Wang Xiaoyun、Yao Qizhi、Yao Chufeng は、計算複雑度の 2 の 63 乗以内で衝突を検出できる、より効率的な SHA-1 攻撃方法を再び公開しました。 つまり、SHA-1 暗号化アルゴリズムでは、非常に小さいながらも衝突が発生する可能性があります。 - 公共 静的文字列sha256(文字列テキスト) {
- メッセージダイジェスト messageDigest = null ;
- 試す {
- messageDigest = MessageDigest.getInstance( "SHA-256" );
- } キャッチ (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- byte[] バイト = messageDigest.digest(text.getBytes());
- Hex.encodeHexString(bytes)を返します。
- }
1.3 HMACシリーズ HMAC は、Hash-based Message Authentication Code の略称で、1996 年に H.Krawezyk、M.Bellare、および R.Canetti によって提案されたハッシュ関数とキーに基づくメッセージ認証方式です。1997 年に RFC2104 として公開され、IPSec やその他のネットワーク プロトコル (SSL など) で広く使用されています。現在では、インターネット セキュリティの事実上の標準となっています。任意の反復ハッシュ関数と組み合わせて使用できます。 HMAC アルゴリズムは暗号化アルゴリズムに似ています。キーが導入され、そのセキュリティは使用されるハッシュ アルゴリズムに完全に依存しなくなります。 - 公共 静的文字列 hmacSha256(文字列テキスト、SecretKeySpec sk) {
- Mac mac = null ;
- 試す {
- mac = Mac.getInstance( "HmacSHA256" );
- } キャッチ (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
- 試す {
- mac.init(sk);
- } キャッチ (InvalidKeyException e) {
- e.printStackTrace();
- }
- byte[] rawHmac = mac.doFinal(text.getBytes());
- 新しい文字列(Base64.encodeBase64(rawHmac))を返します。
不可逆的な暗号化を使用する場合は、SHA256、SHA384、SHA512、および HMAC-SHA256、HMAC-SHA384、HMAC-SHA512 アルゴリズムを使用することをお勧めします。 2. 対称暗号化アルゴリズム 対称暗号化アルゴリズムは、初期のアプリケーションアルゴリズムです。データの暗号化と復号化に同じキーが使用されるため、キー管理が困難になるという問題が発生します。一般的な対称暗号化アルゴリズムには、DES、3DES、AES128、AES192、AES256 などがあります (デフォルトでインストールされた JDK はまだ AES256 をサポートしていないため、jce1.7、jce1.8 にアップグレードするには、対応する jce パッチをインストールする必要があります)。 AES の後の数字はキーの長さを表します。対称暗号化アルゴリズムのセキュリティは比較的低く、イントラネット環境での暗号化と復号化に最適です。 2.1 DES DES は対称暗号化アルゴリズムの分野における代表的なアルゴリズムであり、デフォルトのキーの長さは 56 ビットです。 - / 暗号化
- 公共 静的文字列暗号化(byte[] dataSource, 文字列パスワード){
- 試す {
- SecureRandom ランダム = 新しい SecureRandom();
- DESKeySpec desKeySpec = 新しい DESKeySpec(パスワード.getBytes());
- // キーファクトリーを作成し、それを使用してDESKeySpecを
- SecretKeyFactory の secretKeyFactory = SecretKeyFactory.getInstance( "DES" );
- 秘密キー secretKey = secretKeyFactory.generateSecret(desKeySpec);
- //Cipherオブジェクトは実際に暗号化操作を完了します
- 暗号 cipher = Cipher.getInstance( "DES" );
- // Cipherオブジェクトをキーで初期化する
- cipher.init(Cipher.ENCRYPT_MODE、秘密キー、ランダム);
- //暗号化操作を正式に実行する
- Base64.encodeBase64String(cipher.doFinal(dataSource))を返します。
- } キャッチ (Throwable e) {
- e.printStackTrace();
- }戻る ヌル;
- }
- // 復号化
- 公共 静的文字列復号化(文字列src、文字列パスワード)は例外をスローします{
- // DESアルゴリズムには信頼できる乱数ソースが必要です
- SecureRandom ランダム = 新しい SecureRandom();
- // DESKeySpec オブジェクトを作成する
- DESKeySpec desKeySpec = 新しい DESKeySpec(パスワード.getBytes());
- // キーファクトリーを作成する
- SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DES" );
- // DESKeySpec オブジェクトを SecretKey オブジェクトに変換します
- 秘密キー secretKey = keyFactory.generateSecret(desKeySpec);
- // Cipherオブジェクトは実際に復号化操作を完了します
- 暗号 cipher = Cipher.getInstance( "DES" );
- // Cipherオブジェクトをキーで初期化する
- cipher.init(Cipher.DECRYPT_MODE、秘密キー、ランダム);
- // 実際に復号化操作を開始する
- 新しい文字列(cipher.doFinal(Base64.decodeBase64(src)))を返します。
- }
2.2 3DES 3DES (トリプル DES) は、DES から AES への移行段階の暗号化アルゴリズムです。3 つの 56 ビット キーを使用してデータを 3 回暗号化します。これは DES のより安全な変種です。 DES を基本モジュールとして、グループ化方法を組み合わせてブロック暗号化アルゴリズムを設計します。 3DES はオリジナルの DES よりも安全です。デフォルトのキーの長さは 168 ビットですが、128 ビットもオプションです。 - 公共 静的文字列encryptThreeDESECB(文字列src、文字列キー) {
- 試す{
- DESedeKeySpec dks = new DESedeKeySpec( key .getBytes( "UTF-8" ));
- SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DESede" );
- 秘密鍵 securekey = keyFactory.generateSecret(dks);
-
- 暗号 cipher = Cipher.getInstance( "DESede/ECB/PKCS5Padding" );
- cipher.init(Cipher.ENCRYPT_MODE、セキュアキー);
- byte[] b = cipher.doFinal(src.getBytes( "UTF-8" ));
-
- 文字列 ss = 新しい文字列(Base64.encodeBase64(b));
- ss = ss.replaceAll( "\\+" , "-" );
- ss = ss.replaceAll( "/" , "_" );
- ssを返します。
- } catch(例外ex){
- 例:printStackTrace();
- srcを返します。
- }
- }
-
- 公共 静的文字列decryptThreeDESECB(文字列src、文字列キー) {
- 試す{
- src = src.replaceAll( "-" , "+" );
- src = src.replaceAll( "_" , "/" );
- byte[] bytesrc = Base64.decodeBase64(src.getBytes( "UTF-8" ));
- //
- DESedeKeySpec dks = new DESedeKeySpec( key .getBytes( "UTF-8" ));
- SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DESede" );
- 秘密鍵 securekey = keyFactory.generateSecret(dks);
-
- //
- 暗号 cipher = Cipher.getInstance( "DESede/ECB/PKCS5Padding" );
- cipher.init(Cipher.DECRYPT_MODE、セキュアキー);
- byte[] retByte = cipher.doFinal(bytesrc);
-
- 新しい文字列(retByte, "UTF-8" )を返します。
- } catch(例外ex){
- 例:printStackTrace();
- srcを返します。
- }
- }
2.3 暗号化 AES Advanced Data Encryption Standard は、DES アルゴリズムに対する既知のすべての攻撃に効果的に抵抗できます。デフォルトのキーの長さは 128 ビットですが、192 ビットと 256 ビットも使用できます。ちなみにこのビットはビットを指します。 - プライベート静的最終文字列 defaultCharset = "UTF-8" ;
- プライベート静的最終文字列 KEY_AES = "AES" ;
- プライベート静的最終文字列 KEY_MD5 = "MD5" ;
- プライベート静的メッセージダイジェストmd5ダイジェスト;
- 静的{
- 試す {
- md5Digest = MessageDigest.getInstance(KEY_MD5);
- } キャッチ (NoSuchAlgorithmException e) {
-
- }
- }
- /**
- * 暗号化
- */
- 公共 静的文字列暗号化(文字列データ、文字列キー) {
- doAES(データ、キー、Cipher.ENCRYPT_MODE)を返します。
- }
- /**
- * 復号化
- */
- 公共 静的文字列復号化(文字列データ、文字列キー) {
- doAES(データ、キー、Cipher.DECRYPT_MODE)を返します。
- }
-
-
- /**
- * 暗号化と復号化
- */
- プライベート静的文字列doAES(文字列データ、文字列キー、 intモード) {
- 試す {
- ブール型暗号化 = モード == Cipher.ENCRYPT_MODE;
- byte[] コンテンツ;
- if (暗号化) {
- コンテンツ = data.getBytes(defaultCharset);
- }それ以外{
- コンテンツ = Base64.decodeBase64(data.getBytes());
- }
- SecretKeySpec keySpec = 新しい SecretKeySpec(md5Digest.digest( key .getBytes(defaultCharset))
- 、KEY_AES);
- Cipher cipher = Cipher.getInstance(KEY_AES); // 暗号を作成する
- cipher.init(mode, keySpec); // 初期化
- byte[] 結果 = cipher.doFinal(content);
- if (暗号化) {
- 新しい文字列(Base64.encodeBase64(結果))を返します。
- }それ以外{
- 新しい文字列(結果、defaultCharset)を返します。
- }
- } キャッチ (例外 e) {
- }
- 戻る ヌル;
- }
推奨される対称暗号化アルゴリズムは、AES128、AES192、および AES256 です。 3. 非対称暗号化アルゴリズム 非対称暗号化アルゴリズムには、完全に異なるものの、互いに完全に一致する 2 つのキーがあります。公開鍵と秘密鍵の一致するペアを使用することによってのみ、プレーンテキストの暗号化および復号化プロセスを完了できます。一般的な非対称暗号化には、RSA、SM2 などがあります。 3.1 RS RSA キーは少なくとも 500 ビットの長さである必要があり、通常は 1024 ビットが推奨されます。 - //非対称鍵アルゴリズム
- 公共 静的最終文字列 KEY_ALGORITHM = "RSA" ;
-
- /**
- * キーの長さ。DHアルゴリズムのデフォルトのキーの長さは1024です。
- * キーの長さは64の倍数で、512~65536ビットである必要があります。
- */
- プライベート静的最終int KEY_SIZE = 1024;
- //公開鍵
- プライベート静的最終文字列 PUBLIC_KEY = "RSAPublicKey" ;
- //秘密鍵
- プライベート静的最終文字列 PRIVATE_KEY = "RSAPrivateKey" ;
- /**
- * キーペアを初期化する
- *
- * @return Map パーティAのキーのマップ
- */
- 公共 静的Map<String, Object> initKey() は例外をスローします {
- //キージェネレータをインスタンス化する
- キーペアジェネレーター keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
- // キージェネレータを初期化する
- keyPairGenerator を初期化します(KEY_SIZE);
- //キーペアを生成する
- キーペア keyPair = keyPairGenerator.generateKeyPair();
- //当事者Aの公開鍵
- RSAPublicKey 公開キー = (RSAPublicKey) keyPair.getPublic();
- //当事者Aの秘密鍵
- RSAPrivateKey プライベートキー = (RSAPrivateKey) keyPair.getPrivate();
- //キーをマップに保存する
- Map<String, Object> keyMap = 新しい HashMap<String, Object>();
- keyMap.put(PUBLIC_KEY、公開キー);
- keyMap.put(PRIVATE_KEY、秘密キー);
- keyMapを返します。
- }
- /**
- * 秘密鍵暗号化
- *
- * @param data 暗号化されるデータ
- * @paramキーキー
- * @return byte[] 暗号化されたデータ
- */
- 公共 静的byte[] encryptByPrivateKey(byte[] data, byte[] key )は例外をスローします{
-
- //秘密鍵を取得する
- PKCS8EncodedKeySpec pkcs8KeySpec = 新しい PKCS8EncodedKeySpec(キー);
- KeyFactory のインスタンスを取得します。
- //秘密鍵を生成する
- 秘密鍵 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
- //データ暗号化
- 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
- cipher.init(Cipher.ENCRYPT_MODE、秘密キー);
- cipher.doFinal(data)を返します。
- }
-
- /**
- * 公開鍵暗号化
- *
- * @param data 暗号化されるデータ
- * @paramキーキー
- * @return byte[] 暗号化されたデータ
- */
- 公共 静的byte[] encryptByPublicKey(byte[] data, byte[] key )は例外をスローします {
-
- //キーファクトリーをインスタンス化する
- KeyFactory のインスタンスを取得します。
- // 公開鍵を初期化する
- //キーマテリアル変換
- X509EncodedKeySpec x509KeySpec = 新しい X509EncodedKeySpec(キー);
- //公開鍵を生成する
- 公開鍵 pubKey = keyFactory.generatePublic(x509KeySpec);
- //データ暗号化
- 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
- 暗号を初期化します(Cipher.ENCRYPT_MODE、pubKey);
- cipher.doFinal(data)を返します。
- }
-
- /**
- * 秘密鍵の復号
- *
- * @param data 復号化するデータ
- * @paramキーキー
- * @return byte[] 復号化されたデータ
- */
- 公共 静的byte[] decryptByPrivateKey(byte[] data, byte[] key )は例外をスローします{
- //秘密鍵を取得する
- PKCS8EncodedKeySpec pkcs8KeySpec = 新しい PKCS8EncodedKeySpec(キー);
- KeyFactory のインスタンスを取得します。
- //秘密鍵を生成する
- 秘密鍵 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
- //データの復号
- 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
- cipher.init(Cipher.DECRYPT_MODE、秘密キー);
- cipher.doFinal(data)を返します。
- }
-
- /**
- * 公開鍵復号化
- *
- * @param data 復号化するデータ
- * @paramキーキー
- * @return byte[] 復号化されたデータ
- */
- 公共 静的byte[] decryptByPublicKey(byte[] data, byte[] key )は例外をスローします{
-
- //キーファクトリーをインスタンス化する
- KeyFactory のインスタンスを取得します。
- // 公開鍵を初期化する
- //キーマテリアル変換
- X509EncodedKeySpec x509KeySpec = 新しい X509EncodedKeySpec(キー);
- //公開鍵を生成する
- 公開鍵 pubKey = keyFactory.generatePublic(x509KeySpec);
- //データの復号
- 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
- 暗号を初期化します(Cipher.DECRYPT_MODE、pubKey);
- cipher.doFinal(data)を返します。
- }
-
- /**
- * 秘密鍵を取得する
- *
- * @param keyMap キーマップ
- * @return byte[] 秘密鍵
- */
- 公共 静的byte[] getPrivateKey(Map<String, Object> keyMap) {
- 鍵 key = (キー) keyMap.get(PRIVATE_KEY);
- 戻る キー.getEncoded();
- }
-
- /**
- * 公開鍵を取得する
- *
- * @param keyMap キーマップ
- * @return byte[] 公開鍵
- */
- 公共 静的byte[] getPublicKey(Map<String, Object> keyMap)は例外をスローします{
- 鍵 key = (キー) keyMap.get(PUBLIC_KEY);
- 戻る キー.getEncoded();
- }
4. 暗号化ソルト 暗号化ソルトもよく耳にする概念です。ソルトは、暗号化された文字列と連結された後に暗号化に使用されるランダムな文字列です。ソルトは主に暗号化された文字列のセキュリティを確保するために使用されます。ソルトが付加された暗号化文字列がある場合、ハッカーは特定の手段を使って、暗号化前の文字列ではなく、暗号化前の文字列とソルトの組み合わせである平文を取得できます。これにより、文字列のセキュリティが相対的に向上します。 この記事の一部のアルゴリズムはインターネットからのものであり、そのままコピーして使用することができます。 推奨される暗号化アルゴリズムは次のとおりです。 - 不可逆暗号化: SHA256、SHA384、SHA512、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512
- 対称暗号化アルゴリズム: AES、3DES
- 非対称暗号化アルゴリズム: RSA
この記事はWeChatのパブリックアカウント「Java Journey」から転載したものです。以下のQRコードからフォローできます。この記事を転載する場合は、Java Journey の公開アカウントにお問い合わせください。 |