私はCrypto ++を使用してECBモード(しかしそれでも)の上で手動でCTRを作成しようとしています。 アイデアがある:単一のブロックについてはCrypto ++ CTRモード手動実装
:ちょうどCTRアルゴリズム (私の知る限り)を使用し、複数のブロックのためにECBを使用します。
//We have n block of plain data -> M PlainData M[n]; key; iv; char *CTR; cipher =""; for(i = 0; i<n; i++){ if(i ==0){ CTR = iv; } ei = encryptECB(CTR + i) cipherI = xor(ei, M[i]) cipher += cipherI; }
//私のXOR()2つの文字配列をXORします
void xor(char *s1, char* s2, char *& result, int len){
try{
int i;
for (i = 0; i < len; i++){
int u = s1[i]^s2[i];
result[i] = u;
}
result[i] = '\0';
}
catch (...){
cout << "Errp";
}
}
試験1:100%暗号++ CTR
string auto_ctr(char * s1, long size){
CTR_Mode<AES>::Encryption e;
e.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
string cipherZ;
StringSource s(s1, true,
new StreamTransformationFilter(e,
new StringSink(cipherZ), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING
)
);
return cipherZ;
}
テスト2:マニュアルCTR ECB
string encrypt(char* s1, int size){
ECB_Mode<AES>::Encryption e;
e.SetKey(key, size);
string cipher;
string s(s1, size);
StringSource ss1(s, true,
new StreamTransformationFilter(e,
new StringSink(cipher), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING
) // StreamTransformationFilter
); // StringSource
return cipher;
}
static string manual_ctr(char *plain, long &size){
int nBlocks = size/BLOCK_SIZE;
char* encryptBefore = new char[BLOCK_SIZE];
char *ci = new char[BLOCK_SIZE] ;
string cipher;
for (int i = 0; i < nBlocks; i++){
//If the first loop, CTR = IV
if (i == 0){
memcpy(encryptBefore, iv, BLOCK_SIZE);
}
encryptBefore[BLOCK_SIZE] = '\0';
memcpy(encryptBefore, encryptBefore + i, BLOCK_SIZE);
char *buffer = new char[BLOCK_SIZE];
memcpy(buffer, &plain[i], BLOCK_SIZE);
buffer[BLOCK_SIZE] = '\0';
//Encrypt the CTR
string e1 = encrypt(encryptBefore, BLOCK_SIZE);
//Xor it with m[i] => c[i]
xor((char*)e1.c_str(), buffer, ci, BLOCK_SIZE);
//Append to the summary cipher
/*for (int j = 0; j < BLOCK_SIZE/2; j++){
SetChar(cipher, ci[j], i*BLOCK_SIZE + j);
}*/
cipher += ci;
//Set the cipher back to iv
//memcpy(encryptBefore, ci, BLOCK_SIZE);
}
return cipher;
}
に基づいており、これはテストのために主である:
void main(){
long size = 0;
char * plain = FileUtil::readAllByte("some1.txt", size);
string auto_result = auto_ctr(plain, size);
string manual_result = manual_ctr(plain, size);
getchar();
}
auto_resultは次のとおりです。
「YZ +eÞsÂÙ \bü'\x1a¨Ü_ÙR?Lödå€?ö«Ã¢â、¬Å¡¡¡¡¡¡¯® 1CZS.s%\ x1ei {ÚMØ...Pä¾õ\ x46 \ r5 \tâýï,Ü\x16ç'Qiæ²\x15š€á^ªê] W ÊNqdŒ†¾j%8.Ìù\x6ÞÔÏ '[c \ x19 "
manual_resultは次のとおりです。
「YZ +eÞsÂÙ\bü'\x1a¨Ü_Ù・\x18ýuùの\ nを\ NL \x11Á\x19À†Žaðƒºñ®GäþŽá•\x11ÇYœf+^Q \ X1A \ x13B³'QQμºëÑÌåM\ "\ X12 \x115â\x10¿Ô「> S°‰= \ X18 * \ X1C:²IF'[email protected]ŠŠ¾mGÂzõžÀ\x1eÏ\SëYU¼í」」 >
がproble何ですか私の実装では?
あなたは私の人生を救った! – Andiana
ようこそ。 IVの生成方法はわかりませんが、同じIVを2回使用しないように注意してください。そうでなければ、データを公開している同じキー(ただし異なるデータ)で2回暗号化するとすぐにCTRモードに対する古典的な攻撃だから、同じIVを2回も持っていないことを確認してください(増分後も)。たとえば、 17ブロックを暗号化して5ブロックを暗号化すると、17から22までのIVの全範囲を使用することはできません! – Lery
Crypto ++は、バイト配列として表されるカウンタをインクリメントする目的で[IncrementCounterByOne](http://www.cryptopp.com/docs/ref/misc_8h.html)を提供します。 – jww