インタビュアー: よく使用する暗号化アルゴリズムについて教えてください。

インタビュアー: よく使用する暗号化アルゴリズムについて教えてください。

[[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 値を持つ元のデータを見つける可能性は非常に低くなります。

  1. 公共 静的文字列md5(文字列テキスト) {
  2. メッセージダイジェスト messageDigest = null ;
  3. 試す {
  4. メッセージダイジェスト = MessageDigest.getInstance( "MD5" );
  5. } キャッチ (NoSuchAlgorithmException e) {
  6. e.printStackTrace();
  7. }
  8. byte[] バイト = messageDigest.digest(text.getBytes());
  9. Hex.encodeHexString(bytes)を返します
  10. }

1.2 SHAシリーズ

セキュア ハッシュ アルゴリズム (SHA) は、暗号化ハッシュ関数のファミリであり、FIPS によって認定されたセキュア ハッシュ アルゴリズムです。デジタル メッセージに対応する固定長文字列 (メッセージ ダイジェストとも呼ばれる) を計算できるアルゴリズム。また、入力メッセージが異なる場合、異なる文字列に対応する可能性が高くなります。

2005 年 8 月 17 日の CRYPTO カンファレンスの最後に、Wang Xiaoyun、Yao Qizhi、Yao Chufeng は、計算複雑度の 2 の 63 乗以内で衝突を検出できる、より効率的な SHA-1 攻撃方法を再び公開しました。

つまり、SHA-1 暗号化アルゴリズムでは、非常に小さいながらも衝突が発生する可能性があります。

  1. 公共 静的文字列sha256(文字列テキスト) {
  2. メッセージダイジェスト messageDigest = null ;
  3. 試す {
  4. messageDigest = MessageDigest.getInstance( "SHA-256" );
  5. } キャッチ (NoSuchAlgorithmException e) {
  6. e.printStackTrace();
  7. }
  8. byte[] バイト = messageDigest.digest(text.getBytes());
  9. Hex.encodeHexString(bytes)を返します
  10. }

1.3 HMACシリーズ

HMAC は、Hash-based Message Authentication Code の略称で、1996 年に H.Krawezyk、M.Bellare、および R.Canetti によって提案されたハッシュ関数とキーに基づくメッセージ認証方式です。1997 年に RFC2104 として公開され、IPSec やその他のネットワーク プロトコル (SSL など) で広く使用されています。現在では、インターネット セキュリティの事実上の標準となっています。任意の反復ハッシュ関数と組み合わせて使用​​できます。

HMAC アルゴリズムは暗号化アルゴリズムに似ています。キーが導入され、そのセキュリティは使用されるハッシュ アルゴリズムに完全に依存しなくなります。

  1. 公共 静的文字列 hmacSha256(文字列テキスト、SecretKeySpec sk) {
  2. Mac mac = null ;
  3. 試す {
  4. mac = Mac.getInstance( "HmacSHA256" );
  5. } キャッチ (NoSuchAlgorithmException e) {
  6. e.printStackTrace();
  7. }
  8. 試す {
  9. mac.init(sk);
  10. } キャッチ (InvalidKeyException e) {
  11. e.printStackTrace();
  12. }
  13. byte[] rawHmac = mac.doFinal(text.getBytes());
  14. 新しい文字列(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 ビットです。

  1. / 暗号化
  2. 公共 静的文字列暗号化(byte[] dataSource, 文字列パスワード){
  3. 試す {
  4. SecureRandom ランダム = 新しい SecureRandom();
  5. DESKeySpec desKeySpec = 新しい DESKeySpec(パスワード.getBytes());
  6. // キーファクトリーを作成し、それを使用してDESKeySpecを
  7. SecretKeyFactory の secretKeyFactory = SecretKeyFactory.getInstance( "DES" );
  8. 秘密キー secretKey = secretKeyFactory.generateSecret(desKeySpec);
  9. //Cipherオブジェクトは実際に暗号化操作を完了します
  10. 暗号 cipher = Cipher.getInstance( "DES" );
  11. // Cipherオブジェクトをキーで初期化する
  12. cipher.init(Cipher.ENCRYPT_MODE、秘密キー、ランダム);
  13. //暗号化操作を正式に実行する
  14. Base64.encodeBase64String(cipher.doFinal(dataSource))を返します
  15. } キャッチ (Throwable e) {
  16. e.printStackTrace();
  17. }戻る ヌル;
  18. }
  19. // 復号化
  20. 公共 静的文字列復号化(文字列src、文字列パスワード)は例外をスローします{
  21. // DESアルゴリズムには信頼できる乱数ソースが必要です
  22. SecureRandom ランダム = 新しい SecureRandom();
  23. // DESKeySpec オブジェクトを作成する
  24. DESKeySpec desKeySpec = 新しい DESKeySpec(パスワード.getBytes());
  25. // キーファクトリーを作成する
  26. SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DES" );
  27. // DESKeySpec オブジェクトを SecretKey オブジェクトに変換します
  28. 秘密キー secretKey = keyFactory.generateSecret(desKeySpec);
  29. // Cipherオブジェクトは実際に復号化操作を完了します
  30. 暗号 cipher = Cipher.getInstance( "DES" );
  31. // Cipherオブジェクトをキーで初期化する
  32. cipher.init(Cipher.DECRYPT_MODE、秘密キー、ランダム);
  33. // 実際に復号化操作を開始する
  34. 新しい文字列(cipher.doFinal(Base64.decodeBase64(src)))を返します
  35. }

2.2 3DES

3DES (トリプル DES) は、DES から AES への移行段階の暗号化アルゴリズムです。3 つの 56 ビット キーを使用してデータを 3 回暗号化します。これは DES のより安全な変種です。 DES を基本モジュールとして、グループ化方法を組み合わせてブロック暗号化アルゴリズムを設計します。 3DES はオリジナルの DES よりも安全です。デフォルトのキーの長さは 168 ビットですが、128 ビットもオプションです。

  1. 公共 静的文字列encryptThreeDESECB(文字列src、文字列キー) {
  2. 試す{
  3. DESedeKeySpec dks = new DESedeKeySpec( key .getBytes( "UTF-8" ));
  4. SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DESede" );
  5. 秘密鍵 securekey = keyFactory.generateSecret(dks);
  6.   
  7. 暗号 cipher = Cipher.getInstance( "DESede/ECB/PKCS5Padding" );
  8. cipher.init(Cipher.ENCRYPT_MODE、セキュアキー);
  9. byte[] b = cipher.doFinal(src.getBytes( "UTF-8" ));
  10.  
  11. 文字列 ss = 新しい文字列(Base64.encodeBase64(b));
  12. ss = ss.replaceAll( "\\+" , "-" );
  13. ss = ss.replaceAll( "/" , "_" );
  14. ssを返します
  15. } catch(例外ex){
  16. 例:printStackTrace();
  17. srcを返します
  18. }
  19. }
  20.  
  21. 公共 静的文字列decryptThreeDESECB(文字列src、文字列キー) {
  22. 試す{
  23. src = src.replaceAll( "-" , "+" );
  24. src = src.replaceAll( "_" , "/" );
  25. byte[] bytesrc = Base64.decodeBase64(src.getBytes( "UTF-8" ));
  26. // --復号化キー 
  27. DESedeKeySpec dks = new DESedeKeySpec( key .getBytes( "UTF-8" ));
  28. SecretKeyFactory の keyFactory = SecretKeyFactory.getInstance( "DESede" );
  29. 秘密鍵 securekey = keyFactory.generateSecret(dks);
  30.  
  31. // --Chipher オブジェクトの復号化 
  32. 暗号 cipher = Cipher.getInstance( "DESede/ECB/PKCS5Padding" );
  33. cipher.init(Cipher.DECRYPT_MODE、セキュアキー);
  34. byte[] retByte = cipher.doFinal(bytesrc);
  35.  
  36. 新しい文字列(retByte, "UTF-8" )を返します
  37. } catch(例外ex){
  38. 例:printStackTrace();
  39. srcを返します
  40. }
  41. }

2.3 暗号化

AES Advanced Data Encryption Standard は、DES アルゴリズムに対する既知のすべての攻撃に効果的に抵抗できます。デフォルトのキーの長さは 128 ビットですが、192 ビットと 256 ビットも使用できます。ちなみにこのビットはビットを指します。

  1. プライベート静的最終文字列 defaultCharset = "UTF-8" ;
  2. プライベート静的最終文字列 KEY_AES = "AES" ;
  3. プライベート静的最終文字列 KEY_MD5 = "MD5" ;
  4. プライベート静的メッセージダイジェストmd5ダイジェスト;
  5. 静的{
  6. 試す {
  7. md5Digest = MessageDigest.getInstance(KEY_MD5);
  8. } キャッチ (NoSuchAlgorithmException e) {
  9.  
  10. }
  11. }
  12. /**
  13. * 暗号化
  14. */
  15. 公共 静的文字列暗号化(文字列データ、文字列キー) {
  16. doAES(データ、キー、Cipher.ENCRYPT_MODE)を返します
  17. }
  18. /**
  19. * 復号化
  20. */
  21. 公共 静的文字列復号化(文字列データ、文字列キー) {
  22. doAES(データ、キー、Cipher.DECRYPT_MODE)を返します
  23. }
  24.  
  25.  
  26. /**
  27. * 暗号化と復号化
  28. */
  29. プライベート静的文字列doAES(文字列データ、文字列キー intモード) {
  30. 試す {
  31. ブール型暗号化 = モード == Cipher.ENCRYPT_MODE;
  32. byte[] コンテンツ;
  33. if (暗号化) {
  34. コンテンツ = data.getBytes(defaultCharset);
  35. }それ以外{
  36. コンテンツ = Base64.decodeBase64(data.getBytes());
  37. }
  38. SecretKeySpec keySpec = 新しい SecretKeySpec(md5Digest.digest( key .getBytes(defaultCharset))
  39. 、KEY_AES);
  40. Cipher cipher = Cipher.getInstance(KEY_AES); // 暗号を作成する
  41. cipher.init(mode, keySpec); // 初期化
  42. byte[] 結果 = cipher.doFinal(content);
  43. if (暗号化) {
  44. 新しい文字列(Base64.encodeBase64(結果))を返します
  45. }それ以外{
  46. 新しい文字列(結果、defaultCharset)を返します
  47. }
  48. } キャッチ (例外 e) {
  49. }
  50. 戻る ヌル;
  51. }

推奨される対称暗号化アルゴリズムは、AES128、AES192、および AES256 です。

3. 非対称暗号化アルゴリズム

非対称暗号化アルゴリズムには、完全に異なるものの、互いに完全に一致する 2 つのキーがあります。公開鍵と秘密鍵の一致するペアを使用することによってのみ、プレーンテキストの暗号化および復号化プロセスを完了できます。一般的な非対称暗号化には、RSA、SM2 などがあります。

3.1 RS

RSA キーは少なくとも 500 ビットの長さである必要があり、通常は 1024 ビットが推奨されます。

  1. //非対称鍵アルゴリズム
  2. 公共 静的最終文字列 KEY_ALGORITHM = "RSA" ;
  3.    
  4. /**
  5. * キーの長さ。DHアルゴリズムのデフォルトのキーの長さは1024です。
  6. * キーの長さは64の倍数で、512~65536ビットである必要があります。
  7. */
  8. プライベート静的最終int KEY_SIZE = 1024;
  9. //公開鍵
  10. プライベート静的最終文字列 PUBLIC_KEY = "RSAPublicKey" ;
  11. //秘密鍵
  12. プライベート静的最終文字列 PRIVATE_KEY = "RSAPrivateKey" ;
  13. /**
  14. * キーペアを初期化する
  15. *
  16. * @return Map パーティAのキーのマップ
  17. */
  18. 公共 静的Map<String, Object> initKey() は例外をスローします {
  19. //キージェネレータをインスタンス化する
  20. キーペアジェネレーター keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
  21. // キージェネレータを初期化する
  22. keyPairGenerator を初期化します(KEY_SIZE);
  23. //キーペアを生成する
  24. キーペア keyPair = keyPairGenerator.generateKeyPair();
  25. //当事者Aの公開鍵
  26. RSAPublicKey 公開キー = (RSAPublicKey) keyPair.getPublic();
  27. //当事者Aの秘密鍵
  28. RSAPrivateKey プライベートキー = (RSAPrivateKey) keyPair.getPrivate();
  29. //キーをマップに保存する
  30. Map<String, Object> keyMap = 新しい HashMap<String, Object>();
  31. keyMap.put(PUBLIC_KEY、公開キー);
  32. keyMap.put(PRIVATE_KEY、秘密キー);
  33. keyMapを返します
  34. }
  35. /**
  36. * 秘密鍵暗号化
  37. *
  38. * @param data 暗号化されるデータ
  39. * @paramキーキー
  40. * @return byte[] 暗号化されたデータ
  41. */
  42. 公共 静的byte[] encryptByPrivateKey(byte[] data, byte[] key )は例外をスローします{
  43.  
  44. //秘密鍵を取得する
  45. PKCS8EncodedKeySpec pkcs8KeySpec = 新しい PKCS8EncodedKeySpec(キー);
  46. KeyFactory のインスタンスを取得します。
  47. //秘密鍵を生成する
  48. 秘密鍵 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
  49. //データ暗号化
  50. 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  51. cipher.init(Cipher.ENCRYPT_MODE、秘密キー);
  52. cipher.doFinal(data)を返します
  53. }
  54.  
  55. /**
  56. * 公開鍵暗号化
  57. *
  58. * @param data 暗号化されるデータ
  59. * @paramキーキー
  60. * @return byte[] 暗号化されたデータ
  61. */
  62. 公共 静的byte[] encryptByPublicKey(byte[] data, byte[] key )は例外をスローします {
  63.  
  64. //キーファクトリーをインスタンス化する
  65. KeyFactory のインスタンスを取得します。
  66. // 公開鍵を初期化する
  67. //キーマテリアル変換
  68. X509EncodedKeySpec x509KeySpec = 新しい X509EncodedKeySpec(キー);
  69. //公開鍵を生成する
  70. 公開鍵 pubKey = keyFactory.generatePublic(x509KeySpec);
  71. //データ暗号化
  72. 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  73. 暗号を初期化します(Cipher.ENCRYPT_MODE、pubKey);
  74. cipher.doFinal(data)を返します
  75. }
  76.  
  77. /**
  78. * 秘密鍵の復号
  79. *
  80. * @param data 復号化するデータ
  81. * @paramキーキー
  82. * @return byte[] 復号化されたデータ
  83. */
  84. 公共 静的byte[] decryptByPrivateKey(byte[] data, byte[] key )は例外をスローします{
  85. //秘密鍵を取得する
  86. PKCS8EncodedKeySpec pkcs8KeySpec = 新しい PKCS8EncodedKeySpec(キー);
  87. KeyFactory のインスタンスを取得します。
  88. //秘密鍵を生成する
  89. 秘密鍵 privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
  90. //データの復号
  91. 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  92. cipher.init(Cipher.DECRYPT_MODE、秘密キー);
  93. cipher.doFinal(data)を返します
  94. }
  95.  
  96. /**
  97. * 公開鍵復号化
  98. *
  99. * @param data 復号化するデータ
  100. * @paramキーキー
  101. * @return byte[] 復号化されたデータ
  102. */
  103. 公共 静的byte[] decryptByPublicKey(byte[] data, byte[] key )は例外をスローします{
  104.  
  105. //キーファクトリーをインスタンス化する
  106. KeyFactory のインスタンスを取得します。
  107. // 公開鍵を初期化する
  108. //キーマテリアル変換
  109. X509EncodedKeySpec x509KeySpec = 新しい X509EncodedKeySpec(キー);
  110. //公開鍵を生成する
  111. 公開鍵 pubKey = keyFactory.generatePublic(x509KeySpec);
  112. //データの復号
  113. 暗号 cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  114. 暗号を初期化します(Cipher.DECRYPT_MODE、pubKey);
  115. cipher.doFinal(data)を返します
  116. }
  117.  
  118. /**
  119. * 秘密鍵を取得する
  120. *
  121. * @param keyMap キーマップ
  122. * @return byte[] 秘密鍵
  123. */
  124. 公共 静的byte[] getPrivateKey(Map<String, Object> keyMap) {
  125.   key = (キー) keyMap.get(PRIVATE_KEY);
  126. 戻る キー.getEncoded();
  127. }
  128.  
  129. /**
  130. * 公開鍵を取得する
  131. *
  132. * @param keyMap キーマップ
  133. * @return byte[] 公開鍵
  134. */
  135. 公共 静的byte[] getPublicKey(Map<String, Object> keyMap)は例外をスローします{
  136.   key = (キー) keyMap.get(PUBLIC_KEY);
  137. 戻る キー.getEncoded();
  138. }

4. 暗号化ソルト

暗号化ソルトもよく耳にする概念です。ソルトは、暗号化された文字列と連結された後に暗号化に使用されるランダムな文字列です。ソルトは主に暗号化された文字列のセキュリティを確保するために使用されます。ソルトが付加された暗号化文字列がある場合、ハッカーは特定の手段を使って、暗号化前の文字列ではなく、暗号化前の文字列とソルトの組み合わせである平文を取得できます。これにより、文字列のセキュリティが相対的に向上します。

この記事の一部のアルゴリズムはインターネットからのものであり、そのままコピーして使用することができます。

推奨される暗号化アルゴリズムは次のとおりです。

  • 不可逆暗号化: SHA256、SHA384、SHA512、HMAC-SHA256、HMAC-SHA384、HMAC-SHA512
  • 対称暗号化アルゴリズム: AES、3DES
  • 非対称暗号化アルゴリズム: RSA

この記事はWeChatのパブリックアカウント「Java Journey」から転載したものです。以下のQRコードからフォローできます。この記事を転載する場合は、Java Journey の公開アカウントにお問い合わせください。

<<:  ドローンと農業は互いに補完し合い、数千億ドルの価値がある広大なブルーオーシャンを共同で生み出す

>>:  PCの顔認証ログイン、驚くほど簡単

ブログ    
ブログ    

推薦する

WeChat、サードパーティのエコシステムに統合するインテリジェント会話システム「Xiaowei」を発表

2019年WeChatオープンクラスPROで、WeChat AIチームが開発したインテリジェント対話...

9つの思考フレームワーク:ChatGPTの使用能力を100倍向上させる

1. APEモデル「アクション、目的、期待」(APE) モデルは、アクション、目標、期待を明確にする...

オラクル、企業の言語モデルの導入と微調整を支援するクラウドベースの生成AIサービスを開始

データベース大手のオラクルは最近、Oracle Cloud Infrastructure Gener...

専門家:TikTokのアルゴリズムはユニークではないが、購入者はそれを自ら開発することを待ちきれない

2018年にバイトダンスがカラオケアプリ「Musical.ly」を買収し、TikTokとしてブランド...

Google のアルゴリズムの背後: 検索リクエストは平均 2,400 キロメートルの往復を移動する

3月12日の朝、Googleが検索リクエストを完了するのにかかった時間は1秒未満でしたが、平均往復距...

Siriは中国で禁止されるのでしょうか?国内AI企業がアップルを特許侵害で訴え、高等法院は中国の特許を有効と認定

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

CreditEase の R&D ディレクター、張振氏: 運用・保守ロボットのタスク決定システムの進化

[51CTO.comより引用] 2018年5月18日〜19日、51CTO主催のグローバルソフトウェア...

2030年までに、仕事の70%が人工知能に置き換えられるでしょう。子どもたちが競争力を維持できるよう、私たちはどう支援できるでしょうか?

10年前は多くの人が必死に五線譜を練習していましたが、今ではほとんど誰も使っていません。 5年前は...

モノのインターネット – インド国防軍にとっての可能性

世界がインダストリー4.0へと向かうにつれ、モノのインターネットへの世界的な支出は2022年までに1...

Python、Java、C++がすべて含まれています。このGitHubプロジェクトは、複数の言語で古典的なアルゴリズムを実装しています。

古典的なデータ構造とアルゴリズムをいくつ知っていますか?大企業で面接を受けてみませんか?アルゴリズム...

フィンテックとAI: 金融におけるAIの活用方法

フィンテックの人工知能と機械学習技術は、大規模なデータセットをリアルタイムで分析し、改善を図るのに役...

...

アリババのキャンパス採用の給与は魅力的すぎる、アルゴリズム職の最高給与は72万!最初のオファーを選択するにはどうすればいいですか?

[[248005]]インターネット業界は将来性が有望で、お金を稼げるので就職するには良い場所だと多...

...