...
byte[] passwd = Encoding.UTF8.GetBytes(txtPassword.Text);
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(passwd, passwd,10001);
...
...
let password = getPassword();
let salt = password;
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
function register(){
$password = $_GET['password'];
$username = $_GET['username'];
$hash = hash_pbkdf2('sha256', $password, $password, 100000);
...
import hashlib, binascii
def register(request):
password = request.GET['password']
username = request.GET['username']
dk = hashlib.pbkdf2_hmac('sha256', password, password, 100000)
hash = binascii.hexlify(dk)
store(username, hash)
...
require 'openssl'
...
req = Rack::Response.new
password = req.params['password']
...
key = OpenSSL::PKCS5::pbkdf2_hmac(password, password, 100000, 256, 'SHA256')
...
...
string hashname = ConfigurationManager.AppSettings["hash"];
...
HashAlgorithm ha = HashAlgorithm.Create(hashname);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ hash
を変更することでハッシュ アルゴリズムを操作できるようになります。プログラムが頒布された後は、悪意のあるユーザーが特定の暗号化ハッシュのアルゴリズム パラメーターを判別したかどうかを知るのは極めて難しいため、ユーザー制御のアルゴリズムに関する問題を元に戻すのは非常に困難です。
...
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));
String algorithm = prop.getProperty("hash");
...
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(hashInput.getBytes("UTF-8"));
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ hash
を変更することでハッシュ アルゴリズムを操作できるようになります。プログラムが頒布された後は、悪意のあるユーザーが特定の暗号化ハッシュのアルゴリズム パラメーターを判別したかどうかを知るのは極めて難しいため、ユーザー制御のアルゴリズムに関する問題を元に戻すのは非常に困難です。
require 'openssl'
require 'csv'
...
CSV.read(my_file).each do |row|
...
hash = row[4]
...
digest = OpenSSL::Digest.new(hash, data)
...
end
Example 1
のコードは正常に実行されますが、この機能にアクセスできる者であれば誰でも CSV ファイルから hash
を変更し、ハッシュ アルゴリズムを操作できます。プログラムが頒布された後は、悪意のあるユーザーが特定の暗号化ハッシュのアルゴリズム パラメーターを判別したかどうかを知るのは極めて難しいため、ユーザー制御のアルゴリズムに関する問題を元に戻すのは非常に困難です。
...
String minimumBits = prop.getProperty("minimumbits");
Hashing.goodFastHash(minimumBits).hashString("foo", StandardCharsets.UTF_8);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ minimumBits
を変更して、パスワードのハッシュに使用する最小ビットを操作できるようになります。パスワード ハッシュの最小ビットが悪意のあるユーザーによって設定されたかどうかを知る方法はないので、プログラムを頒布した後に、ユーザー制御の最小ビットに関する問題を元に戻すのは困難です。
string salt = ConfigurationManager.AppSettings["salt"];
...
Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes("password", Encoding.ASCII.GetBytes(salt));
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ salt
を変更することで鍵またはパスワードの導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
salt = getenv("SALT");
PKCS5_PBKDF2_HMAC(pass, sizeof(pass), salt, sizeof(salt), ITERATION, EVP_sha512(), outputBytes, digest);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも、環境変数 SALT
を変更することで、鍵またはパスワードの導出に使用される salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
Properties prop = new Properties();
prop.load(new FileInputStream("local.properties"));
String salt = prop.getProperty("salt");
...
PBEKeySpec pbeSpec=new PBEKeySpec(password);
SecretKeyFactory keyFact=SecretKeyFactory.getInstance(CIPHER_ALG);
PBEParameterSpec defParams=new PBEParameterSpec(salt,100000);
Cipher cipher=Cipher.getInstance(CIPHER_ALG);
cipher.init(cipherMode,keyFact.generateSecret(pbeSpec),defParams);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ salt
を変更することで鍵またはパスワードの導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
app.get('/pbkdf2', function(req, res) {
...
let salt = req.params['salt'];
crypto.pbkdf2(
password,
salt,
iterations,
keyLength,
"sha256",
function (err, derivedKey) { ... }
);
}
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ salt
を変更することで鍵またはパスワードの導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
@property (strong, nonatomic) IBOutlet UITextField *inputTextField;
...
NSString *salt = _inputTextField.text;
const char *salt_cstr = [salt cStringUsingEncoding:NSUTF8StringEncoding];
...
CCKeyDerivationPBKDF(kCCPBKDF2,
password,
passwordLen,
salt_cstr,
salt.length,
kCCPRFHmacAlgSHA256,
100000,
derivedKey,
derivedKeyLen);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも UITextField inputTextField
のテキストを変更することで鍵またはパスワードの導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
function register(){
$password = $_GET['password'];
$username = $_GET['username'];
$salt = getenv('SALT');
$hash = hash_pbkdf2('sha256', $password, $salt, 100000);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも、環境変数 SALT
を変更することで、鍵またはパスワードの導出に使用される salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
import hashlib, binascii
def register(request):
password = request.GET['password']
username = request.GET['username']
salt = os.environ['SALT']
dk = hashlib.pbkdf2_hmac('sha256', password, salt, 100000)
hash = binascii.hexlify(dk)
store(username, hash)
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも、環境変数 SALT
を変更することで、鍵またはパスワードの導出に使用される salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
salt=io.read
key = OpenSSL::PKCS5::pbkdf2_hmac(pass, salt, iter_count, 256, 'SHA256')
...
Example 1
のコードは正常に実行されますが、この機能にアクセスできる者であれば誰でも salt
のテキストを変更し、鍵やパスワードの導出に使用された salt を操作できます。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
@IBOutlet weak var inputTextField : UITextField!
...
let salt = (inputTextField.text as NSString).dataUsingEncoding(NSUTF8StringEncoding)
let saltPointer = UnsafePointer<UInt8>(salt.bytes)
let saltLength = size_t(salt.length)
...
let algorithm : CCPBKDFAlgorithm = CCPBKDFAlgorithm(kCCPBKDF2)
let prf : CCPseudoRandomAlgorithm = CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA256)
CCKeyDerivationPBKDF(algorithm,
passwordPointer,
passwordLength,
saltPointer,
saltLength,
prf,
100000,
derivedKeyPointer,
derivedKeyLength)
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも UITextField inputTextField
のテキストを変更することで鍵またはパスワードの導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
salt = getenv("SALT");
password = crypt(getpass("Password:"), salt);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも、環境変数 SALT
を変更することで、パスワードのハッシュに使用される salt を操作できるようになります。さらに、このコードは、パスワードの暗号ハッシュには使用してはならない crypt()
関数を使用しています。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
func someHandler(w http.ResponseWriter, r *http.Request){
r.parseForm()
salt := r.FormValue("salt")
password := r.FormValue("password")
...
sha256.Sum256([]byte(salt + password))
}
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも環境変数 salt
を変更することでパスワードのハッシュに使用する salt を操作できるようになります。さらに、このコードは、パスワードの暗号ハッシュには使用してはならない Sum256
暗号化ハッシュ関数を使用しています。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
Properties prop = new Properties();
prop.load(new FileInputStream("local.properties"));
String salt = prop.getProperty("salt");
...
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(salt);
return digest.digest(password.getBytes("UTF-8"));
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ salt
を変更することでパスワードのハッシュに使用する salt を操作できるようになります。パスワード ハッシュの salt が悪意のあるユーザーによって判読されたかどうかを知る方法はほとんどないので、プログラムを頒布した後に、ユーザー制御の salt に関する問題を元に戻すのは非常に困難です。
import hashlib, binascii
def register(request):
password = request.GET['password']
username = request.GET['username']
salt = os.environ['SALT']
hash = hashlib.md5("%s:%s" % (salt, password,)).hexdigest()
store(username, hash)
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でも環境変数 SALT
を変更することでパスワードのハッシュに使用する salt を操作できるようになります。さらに、このコードは、パスワードの暗号ハッシュには使用してはならない md5()
暗号化ハッシュ関数を使用しています。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
salt = req.params['salt']
hash = @userPassword.crypt(salt)
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもパラメーター salt
を変更することでパスワードのハッシュに使用する salt を操作できるようになります。さらに、このコードは、パスワードの暗号ハッシュには使用してはならない String#crypt()
関数を使用しています。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
let saltData = userInput.data(using: .utf8)
sharedSecret.hkdfDerivedSymmetricKey(
using: SHA256.self,
salt: saltData,
sharedInfo: info,
outputByteCount: 1000
)
例 1
のコードは正常に実行されますが、この機能を使用すれば誰でも userInput
の値を変更することで暗号鍵の導出に使用する salt を操作できるようになります。悪意のあるユーザーによってパスワード ハッシュの salt が判別されたかどうかを把握するのは極めて難しいため、プログラムを頒布した後に、ユーザー制御による salt に関する問題を元に戻すのは非常に困難です。
...
String seed = prop.getProperty("seed");
Hashing.murmur3_32_fixed(Integer.parseInt(seed)).hashString("foo", StandardCharsets.UTF_8);
...
Example 1
のコードは正常に実行されますが、この機能を使用すれば誰でもプロパティ seed
を変更して、パスワードのハッシュに使用するシードを操作できるようになります。パスワード ハッシュのシードが悪意のあるユーザーによって判読されたかどうかを知る方法はないので、プログラムを頒布した後に、ユーザー制御のシードに関する問題を元に戻すのは困難です。k
が必要です。この値は、暗号的にランダムで、秘密にされ、再利用されないようにする必要があります。攻撃者が k
の値を推測できる場合、または署名者をだまして提供された値を使用させることができる場合、攻撃者は秘密鍵をリカバリしてから、正当な署名者になりすまして署名を偽造することができます。同様に、k
の値が複数のメッセージに署名するために再利用される場合も、攻撃者が秘密鍵をリカバリできます。k
が必要です。この値は、暗号的にランダムで、秘密にされ、再利用されないようにする必要があります。攻撃者が k
の値を推測できる場合、または署名者をだまして提供された値を使用させることができる場合、攻撃者は秘密鍵をリカバリしてから、正当な署名者になりすまして署名を偽造することができます。同様に、k
の値が複数のメッセージに署名するために再利用される場合も、攻撃者が秘密鍵をリカバリできます。k
が必要です。この値は、暗号的にランダムで、秘密にされ、再利用されないようにする必要があります。攻撃者が k
の値を推測できる場合、または署名者をだまして提供された値を使用させることができる場合、攻撃者は秘密鍵をリカバリしてから、正当な署名者になりすまして署名を偽造することができます。同様に、k
の値が複数のメッセージに署名するために再利用される場合も、攻撃者が秘密鍵をリカバリできます。k
が必要です。この値は、暗号的にランダムで、秘密にされ、再利用されないようにする必要があります。攻撃者が k
の値を推測できる場合、または署名者をだまして提供された値を使用させることができる場合、攻撃者は秘密鍵をリカバリしてから、正当な署名者になりすまして署名を偽造することができます。同様に、k
の値が複数のメッセージに署名するために再利用される場合も、攻撃者が秘密鍵をリカバリできます。
...
DSA dsa = new DSACryptoServiceProvider(1024);
...
...
DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL);
...
...
dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160)
privatekey := new(dsa.PrivateKey)
privatekey.PublicKey.Parameters = *params
dsa.GenerateKey(privatekey, rand.Reader)
...
...
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA256PRNG", "SUN");
keyGen.initialize(1024, random);
...
...
from Crypto.PublicKey import DSA
key = DSA.generate(1024)
...
require 'openssl'
...
key = OpenSSL::PKey::DSA.new(1024)
...
EVP_SignUpdate
へのコールをスキップするため、データに基づかずに署名が作成されます。
...
rv = EVP_SignInit(ctx, EVP_sha512());
...
rv = EVP_SignFinal(ctx, sig, &sig_len, key);
...
update
へのコールをスキップするため、データに基づかずに署名が作成されます。
...
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(keyPair.getPrivate());
...
byte[] signatureBytes = sig.sign();
...
...
DSA dsa1 = new DSACryptoServiceProvider(Convert.ToInt32(TextBox1.Text));
...
key_len
を決定できる使用例もわずかにありますが、その場合でも、それが数値であり、鍵サイズとして適切な値の範囲に収まっていることを確認するだけの防御が求められます。ほとんどの使用例において、十分に大きな数字をハードコーディングすることが求められます。
...
dsa.GenerateParameters(params, rand.Reader, key_len)
privatekey := new(dsa.PrivateKey)
privatekey.PublicKey.Parameters = *params
dsa.GenerateKey(privatekey, rand.Reader)
...
key_len
を指定できなくてはいけない場合がまれにあります。その場合、それが数値であり、鍵サイズとして適切な値の範囲に収まっていることを確認する必要があります。ほとんどの使用例において、ハードコーディングされた十分に大きな鍵サイズを選択してください。
require 'openssl'
...
key_len = io.read.to_i
key = OpenSSL::PKey::DSA.new(key_len)
...
key_len
を決定できる使用例もわずかにありますが、その場合でも、それが数値であり、鍵サイズとして適切な値の範囲に収まっていることを確認するだけの防御が求められます。ほとんどの使用例において、十分に大きな数字をハードコーディングすることが求められます。例 2: 次のコードは、
Properties props = System.getProperties();
...
properties.setProperty("org.jcp.xml.dsig.secureValidation", "false");
XMLCryptoContext.setProperty
を使用して XML 署名の安全な検証を無効にします。
DOMCryptoContext cryptoContext = new DOMCryptoContext() {...};
...
cryptoContext.setProperty("org.jcp.xml.dsig.secureValidation", false);
...
CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
key,
kCCKeySizeDES, // 64-bit key size
iv,
plaintext,
sizeof(plaintext),
ciphertext,
sizeof(ciphertext),
&numBytesEncrypted);
...
...
let iv = getTrueRandomIV()
...
let cStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmDES),
UInt32(kCCOptionPKCS7Padding),
key,
keyLength,
iv,
plaintext,
plaintextLength,
ciphertext,
ciphertextLength,
&numBytesEncrypted)
...
String
に変換するとエントロピを大幅に失います。String
に変換されているString
に変換しています。
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
...
KeyGenerator keygen = KeyGenerator.newInstance("AES");
...
SecretKey cryptoKey = keygen.generateKey();
byte[] rawCryptoKey = cryptoKey.getEncoded();
...
String key = new String(rawCryptoKey);
...
String
に変換していますが、コンストラクターに文字セットの有効な範囲外のバイトを加えた場合、何が起こるかは不明です。そのままでは、key
は元の暗号鍵 rawCryptoKey
と比べて大幅にエントロピを失う可能性があります。
static public byte[] EncryptWithRSA(byte[] plaintext, RSAParameters key) {
try {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(key);
return rsa.Encrypt(plaintext, false);
}
catch(CryptographicException e) {
Console.WriteLine(e.Message);
return null;
}
}
void encrypt_with_rsa(BIGNUM *out, BIGNUM *in, RSA *key) {
u_char *inbuf, *outbuf;
int ilen;
...
ilen = BN_num_bytes(in);
inbuf = xmalloc(ilen);
BN_bn2bin(in, inbuf);
if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key, RSA_NO_PADDING)) <= 0) {
fatal("encrypt_with_rsa() failed");
}
...
}
...
import "crypto/rsa"
...
plaintext := []byte("Attack at dawn")
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, &k.PublicKey, plaintext)
...
public Cipher getRSACipher() {
Cipher rsa = null;
try {
rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");
}
catch (java.security.NoSuchAlgorithmException e) {
log("this should never happen", e);
}
catch (javax.crypto.NoSuchPaddingException e) {
log("this should never happen", e);
}
return rsa;
}
+ (NSData *) encryptData:(NSData *) plaintextData withKey:(SecKeyRef *) publicKey {
CFErrorRef error = nil;
NSData *ciphertextData = (NSData*) CFBridgingRelease(
SecKeyCreateEncryptedData(*publicKey,
kSecKeyAlgorithmRSAEncryptionPKCS1,
(__bridge CFDataRef) plaintextData,
&error));
if (error) {
// handle error ...
}
return ciphertextData;
}
function encrypt($input, $key) {
$output='';
openssl_public_encrypt($input, $output, $key, OPENSSL_NO_PADDING);
return $output;
}
...
from Crypto.PublicKey import RSA
message = 'Attack at dawn'
key = RSA.importKey(open('pubkey.der').read())
ciphertext = key.encrypt(message)
...
require 'openssl'
...
key = OpenSSL::PKey::RSA.new 2048
public_encrypted = key.public_encrypt(data) #padding type not specified
...
Example 1
では、OpenSSL::PKey::RSA#public_encrypt
は文字列でのみ呼び出され、使用するパディングの種類を指定しません。パディングの初期設定は OpenSSL::PKey::RSA::PKCS1_PADDING
です。
func encrypt(data plaintextData:Data, publicKey:SecKey) throws -> Data {
var error: Unmanaged<CFError>?
guard let ciphertextData = SecKeyCreateEncryptedData(publicKey,
.rsaEncryptionPKCS1,
plaintextData as CFData,
&error) else {
throw error!.takeRetainedValue() as Error
}
return ciphertextData as Data;
}
...
Blob iv = Blob.valueOf('1234567890123456');
Blob encrypted = Crypto.encrypt('AES128', encKey, iv, input);
...
byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
using (SymmetricAlgorithm aesAlgo = SymmetricAlgorithm.Create("AES"))
{
...
aesAlgo.IV = iv;
...
}
unsigned char * iv = "12345678";
EVP_EncryptInit_ex(&ctx, EVP_idea_gcm(), NULL, key, iv);
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
)
...
block, err := aes.NewCipher(key)
...
mode := cipher.NewCBCEncrypter(block, key)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
byte[] iv = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
IvParameterSpec ips = new IvParameterSpec(iv);
...
const iv = "hardcoded"
const cipher = crypto.createCipheriv("aes-192-ccm", key, iv)
...
NSString *iv = @"1234567812345678"; //Bad idea to hard code IV
char ivPtr[kCCBlockSizeAES128];
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSASCIIStringEncoding];
...
ccStatus = CCCrypt( kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
[key cStringUsingEncoding:NSASCIIStringEncoding],
kCCKeySizeAES128,
[ivPtr], /*IV should be something random (not null and not constant)*/
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted
);
nil
) 場合は、すべてがゼロの IVが使用されます。
from Crypto.Cipher import AES
from Crypto import Random
...
key = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CTR, IV=key)
require 'openssl'
...
cipher = OpenSSL::Cipher::AES.new('256-GCM')
cipher.encrypt
@key = cipher.random_key
cipher.iv=@key
encrypted = cipher.update(data) + cipher.final # encrypts data without hardcoded IV
...
...
let cStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES128),
UInt32(kCCOptionPKCS7Padding),
key,
keyLength,
"0123456789012345",
plaintext,
plaintextLength,
ciphertext,
ciphertextLength,
&numBytesEncrypted)
nil
) 場合は、すべてがゼロの IVが使用されます。
...
var objAesCryptoService = new AesCryptoServiceProvider();
objAesCryptoService.Mode = CipherMode.ECB;
objAesCryptoService.Padding = PaddingMode.PKCS7;
objAesCryptoService.Key = securityKeyArray;
var objCrytpoTransform = objAesCryptoService.CreateEncryptor();
...
EVP_EncryptInit_ex(&ctx, EVP_aes_256_ecb(), NULL, key, iv);
...
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
...
...
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
...
...
ccStatus = CCCrypt( kCCEncrypt,
kCCAlgorithmAES,
kCCOptionECBMode, // Uses ECB mode
key,
kCCKeySizeAES128,
iv,
plaintext,
sizeof(plaintext),
ciphertext,
sizeof(ciphertext),
&numBytesEncrypted);
...
from Crypto.Cipher import AES
from Crypto import Random
...
key = Random.new().read(AES.block_size)
random_iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_ECB, random_iv)
require 'openssl'
...
cipher = OpenSSL::Cipher::AES.new('256-ECB')
...
ccStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmAES128),
UInt32(kCCOptionECBMode),
keyData.bytes,
keyLength,
keyData.bytes,
data.bytes,
data.length,
cryptData.mutableBytes,
cryptData.length,
&numBytesEncrypted)
...
static public byte[] EncryptWithRSA(byte[] plaintext, RSAParameters key) {
try {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
rsa.ImportParameters(key);
return rsa.Encrypt(plaintext, true);
}
catch(CryptographicException e) {
Console.WriteLine(e.Message);
return null;
}
}
EVP_PKEY * get_RSA_key() {
unsigned long err;
EVP_PKEY * pkey;
RSA * rsa;
rsa = RSA_generate_key(512, 35, NULL, NULL);
if (rsa == NULL) {
err = ERR_get_error();
printf("Error = %s\n",ERR_reason_error_string(err));
return NULL;
}
pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, rsa);
return pkey;
}
...
myPrivateKey := rsa.GenerateKey(rand.Reader, 1024);
...
public static KeyPair getRSAKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512);
KeyPair key = keyGen.generateKeyPair();
return key;
}
...
crmfObject = crypto.generateCRMFRequest(
"CN=" + name.value,
password.value,
authenticator,
keyTransportCert,
"setCRMFRequest();",
512, null, "rsa-dual-use");
...
...
CCCrypt(kCCEncrypt,
kCCAlgorithmDES,
kCCOptionPKCS7Padding,
key,
kCCKeySizeDES, // 64-bit key size
iv,
plaintext,
sizeof(plaintext),
ciphertext,
sizeof(ciphertext),
&numBytesEncrypted);
...
...
$keysize = 1024;
$options = array('private_key_bits' => $keysize, 'private_key_type' => OPENSSL_KEYTYPE_RSA);
$res = openssl_pkey_new($options);
...
...
from Crypto.PublicKey import RSA
key = RSA.generate(1024)
...
require 'openssl'
...
pkey = OpenSSL::PKey::RSA.new 1024
...
...
let iv = getTrueRandomIV()
...
let cStatus = CCCrypt(UInt32(kCCEncrypt),
UInt32(kCCAlgorithmDES),
UInt32(kCCOptionPKCS7Padding),
key,
UInt32(kCCKeySizeDES), // 64-bit key size
iv,
plaintext,
plaintextLength,
ciphertext,
ciphertextLength,
&numBytesEncrypted)
...
EVP_DecryptUpdate
へのコールをスキップしており、暗号文の複合化に失敗する原因になります。
...
EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, key, iv);
...
if(!EVP_DecryptFinal_ex(&ctx, outBuf+outBytes, &tmpOutBytes))
prtErrAndExit(1, "ERROR: EVP_DecryptFinal_ex did not work...\n");
...
KeyGenerator
の初期化ステップをスキップし、推奨より小さな鍵を使用することが考えられます。
...
final String CIPHER_INPUT = "123456ABCDEFG";
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecretKey secretKey = keyGenerator.generateKey();
byte[] byteKey = secretKey.getEncoded();
....
OpenSSL::Cipher#update
へのコールを省略します。その結果、暗号文を解読できません。
require 'openssl'
...
decipher = OpenSSL::Cipher::AES.new(128, :GCM)
decipher.decrypt
decipher.key = key
decipher.iv = iv
plain = decipher.final #missed update method
...
import (
"crypto/aes"
"crypto/cipher"
"os"
)
...
iv = b'1234567890123456'
CTRstream = cipher.NewCTR(block, iv)
CTRstream.XORKeyStream(plaintext, ciphertext)
...
f := os.Create("data.enc")
f.Write(ciphertext)
f.Close()
Example 1
では、iv
が定数初期化ベクトルとして設定されているため、再利用攻撃を受けやすくなります。
...
const cipher = crypto.createCipheriv("AES-256-CTR", key, 'iv')
const ciphertext = cipher.update(plaintext, 'utf8');
cipher.final();
fs.writeFile('my_encrypted_data', ciphertext, function (err) {
...
});
from Crypto.Cipher import AES
from Crypto import Random
...
key = Random.new().read(AES.block_size)
iv = b'1234567890123456'
cipher = AES.new(key, AES.MODE_CTR, iv, counter)
...
encrypted = cipher.encrypt(data)
f = open("data.enc", "wb")
f.write(encrypted)
f.close()
...
Example 1
では、iv
が定数初期化ベクトルとして設定されているため、再利用攻撃を受けやすくなります。
require 'openssl'
...
cipher = OpenSSL::Cipher.new('AES-256-CTR')
cipher.encrypt
cipher.iv='iv'
...
encrypted = cipher.update(data) + cipher.final
File.open('my_encrypted_data', 'w') do |file|
file.write(encrypted)
end
Example 1
では、OpenSSL::Cipher#iv=
が定数初期化ベクトルとして設定されているため、再利用攻撃を受けやすくなります。