コンテンツにスキップ

Use non-random initialization vector (IV)

非ランダムな初期化ベクトル(IV)の使用

説明

非ランダムな初期化ベクトルを使用すると、アプリケーションが辞書攻撃に対して脆弱になります。

以下の例は、ハードコードされた静的IVの不適切な設定を示しています。

public; class InsecureExample {
    @Override
    public void; run() throws; Exception;{
        byte;[]; IV = "0123456789abcdef".getBytes();
        String; clearText = "Jan van Eyck was here 1434";
        String; key = "ThisIs128bitSize";
        SecretKeySpec; skeySpec = new SecretKeySpec(key.getBytes(), "AES");
        Cipher; cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher;.init(Cipher.ENCRYPT_MODE;, skeySpec;, new; IvParameterSpec(IV))
        byte;[]; encryptedMessage = cipher.doFinal(clearText.getBytes());
        Log;.i(TAG, String.format("Message: %s";, Base64;.encodeToString(encryptedMessage, Base64.DEFAULT;)))
    }
}

推奨事項

IVに関連する暗号上の欠陥を軽減するために、以下の推奨事項を考慮してください。

  • 暗号化ごとの一意のIV: 暗号化操作ごとに一意のIVを使用することが不可欠です。同じキーで同じIVを再利用すると、暗号文のパターンが露呈したり、リプレイ攻撃などの攻撃を容易にしたりするなど、セキュリティ上の脆弱性につながる可能性があります。
  • ランダム性: IVは、暗号論的に安全な擬似乱数生成器(Javaの場合はSecureRandom、Swiftの場合はSecRandomCopyBytes)を使用して生成する必要があります。このランダム性により、攻撃者がIVを予測できなくなり、暗号化のセキュリティが低下するのを防ぐことができます。
  • IVの長さ: IVの長さは、使用されている暗号化アルゴリズムに依存します。例えば、AESの場合、IVの長さは通常、AES-128で128ビット(16バイト)、AES-192で192ビット(24バイト)、AES-256で256ビット(32バイト)です。暗号化アルゴリズムに適切な長さのIVを使用することが重要です。
import java.security.SecureRandom
import javax.crypto.spec.IvParameterSpec

object IVGenerator {
        fun generateIV(length: Int): ByteArray {
                val iv = ByteArray(length)
                val secureRandom = SecureRandom()
                secureRandom.nextBytes(iv)
                return iv
        }
}

fun main() {
        val ivLength = 16 // Length of IV in bytes
        val iv = IVGenerator.generateIV(ivLength)
        println("Generated IV: ${bytesToHex(iv)}")
}

fun bytesToHex(bytes: ByteArray): String {
        return bytes.joinToString("") { "%02x".format(it) }
}
import CryptoKit

func generateIV(length: Int) -> Data {
        var iv = Data(count: length)
        _ = iv.withUnsafeMutableBytes { ivPtr in
                guard let ivBaseAddress = ivPtr.baseAddress else { return }
                _ = SecRandomCopyBytes(kSecRandomDefault, length, ivBaseAddress)
        }
        return iv
}

let ivLength = 16 // Length of IV in bytes
let iv = generateIV(length: ivLength)
print("Generated IV: \(iv.hexEncodedString())")

extension Data {
        func hexEncodedString() -> String {
                return map { String(format: "%02hhx", $0) }.joined()
        }
}
import 'dart:typed_data';
import 'dart:math';

Uint8List generateIV(int length) {
    final random = Random.secure();
    return Uint8List.fromList(List.generate(length, (index) => random.nextInt(256)));
}

void main() {
    final ivLength = 16; // Length of IV in bytes
    final iv = generateIV(ivLength);
    print('Generated IV: ${bytesToHex(iv)}');
}

String bytesToHex(Uint8List bytes) {
    return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
}

リンク

標準

  • OWASP_MASVS_L1:
    • MSTG_CRYPTO_2
    • MSTG_CRYPTO_3
    • MSTG_CRYPTO_4
  • OWASP_MASVS_L2:
    • MSTG_CRYPTO_2
    • MSTG_CRYPTO_3
    • MSTG_CRYPTO_4
  • PCI_STANDARDS:
    • REQ_2_2
    • REQ_3_6
    • REQ_3_7
    • REQ_4_2
    • REQ_6_2
  • OWASP_MASVS_v2_1:
    • MASVS_CRYPTO_1
    • MASVS_CRYPTO_2
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_6_7
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
  • CNIL_FOR_DEVELOPERS:
    • DEVELOPERS_4_1_4
  • HIPAA_CONTROLS:
    • SECURITY251
    • SECURITY212
    • SECURITY213