मैं सी ++ कोड को सी # पर बंद करने की कोशिश कर रहा हूं और अधिकांश भाग के लिए यह काम कर रहा है, हालांकि केवल लूप के पहले 3 राउंड के लिए। चौथे दौर में, इनपुट ब्लॉक के लिए बाइट अलग-अलग होने लगते हैं और मुझे समझ में नहीं आता क्यों। अगर हम मानते हैं कि सी ++ संस्करण सही कार्यान्वयन है, तो सी # कोड चौथे दौर में एक अलग परिणाम क्यों दे रहा है। नीचे मेरे परिणाम और कोड (सी ++/सीएलआर और सी # के लिए दोनों कंसोल अनुप्रयोग)एन्क्रिप्शन एल्गोरिदम के इस सी # पोर्ट के चौथे दौर पर मेरे बाइट अलग क्यों हैं?
मुझे लगता है कि एईएस को पारित होने से पहले प्रत्येक दौर में इनपुट ब्लॉक बनाया जा रहा है, जिस तरह से कुछ अलग है (सी ++ में आधार 256, से_base_256 और से_base_256) में कनवर्ट करने का एक तरीका है, लेकिन सी # में मैं बेस 256 बाइट सरणी को सीधे BigInteger में परिवर्तित कर रहा हूं और फिर बाइट सरणी पर वापस आ रहा हूं। मुझे नहीं पता कि प्रत्येक के पहले 3 राउंड के लिए समान इनपुट ब्लॉक मान क्यों होंगे, लेकिन चौथे के लिए नहीं।
संपादित करें: अधिक डिबगिंग मैं को संकुचित होता जहां समस्या पाश के लिए में इस लाइन ही दिखा शुरू होने के बाद जब मैं = 2 (गोल 3)
BigInteger AESResult = new BigInteger(t);
की एईएस एन्क्रिप्शन के बाद ब्लॉक मेरी बाइट सरणी टी
शामिल23, 111, 30, 144, 117, 161, 87, 113, 157, 52, 215, 157, 130, 135, 20, 184
लेकिन जब मैं इन बाइट्स को उपरोक्त रेखा का उपयोग करके बिगइंटर में परिवर्तित करता हूं, अचानक अचानक मूल्य पर संकेत नकारात्मक हो जाता है और यह सब वहां से नीचे की ओर जाता है। मूल्य पिछले राउंड में स्थानीय विंडो में भी प्रदर्शित नहीं होता है।
आउटपुट परिणामों
ROUND 1
इनपुट
सी ++ 224,144,103,1,0,0,0,0,0,0,0,0,0,0,0, 0,
सी # 224,144,103,1,0,0,0,0,0,0,0,0,0,0,0,0,
एईएस एन्क्रिप्टेड
सी ++ 175,19,208,16,98,242,219,41,136,137,124,214,117,242,222, 20,
सी # 175,19,208,16,98, 242,219,41,136,137,124,214,117,242,222,20,ROUND 2
इनपुट
सी ++ 168,68,153,2,0,0,0,0,0,0,0,0,1,0,0,0,
सी # 168,68,153,2,0,0,0,0,0,0,0,0,1,0,0,0,
एईएस एन्क्रिप्टेड
सी ++ 182,186,181,102,204,102,32,32,232,213,226,133,59,128,225,109,
सी # 182,186,181,102,204,102,32,32,232,213,226,133,59,128,225,109,राउंड 3
इनपुट
सी ++ 150,126,97,5,0,0,0,0,0,0,0,0,2,0,0,0,
सी # 150,126,97,5,0,0, 0,0,0,0,0,0,2,0,0,0,
एईएस एन्क्रिप्टेड
सी ++ 23,111,30,144,117,161,87,113,157,52,215,157,130,135,20,184,
सी # 23,111,30,144,117,161,87,113,157,52,215,157,130,135,20,184,ROUND 4
इनपुट
सी ++ 191,210,191,0,0,0,0,0,0 , 0,0,0,3,0,0,0,
सी # 191,255,174,252,0,0,0,0,0,0,0,0,3,0,0,0,
एईएस एन्क्रिप्टेड
सी ++ 130,187,182,115,251,12,63,157,109,110,234,35,137,208,172,203,
सी # 248,197,125,177,46,103,91,217,246,8,202,219,115,4,213,37,
सी ++ CLR कंसोल आवेदन
// ConsoleApplication2.cpp : main project file.
#include "stdafx.h"
using namespace System;
using namespace System::Security::Cryptography;
void unpack(unsigned int a, unsigned char *b)
{ /* unpack bytes from a word */
b[0] = unsigned char(a);
b[1] = unsigned char(a >> 8);
b[2] = unsigned char(a >> 16);
b[3] = unsigned char(a >> 24);
}
array<unsigned char>^ AES_encrypt_block(array<unsigned char>^ plainText)
{
array<unsigned char>^ key = gcnew array<unsigned char>(16);
key[0] = 0x01; key[1] = 0x01; key[2] = 0x01; key[3] = 0x01; key[4] = 0x01; key[5] = 0x01; key[6] = 0x01; key[7] = 0x01;
key[8] = 0x01; key[9] = 0x01; key[10] = 0x01; key[11] = 0x01; key[12] = 0x01; key[13] = 0x01; key[14] = 0x01; key[15] = 0x01;
AesManaged^ AES = gcnew AesManaged();
AES->BlockSize = 128;
AES->KeySize = 128;
AES->Key = key;
AES->Mode = CipherMode::ECB;
AES->Padding = PaddingMode::None;
array<unsigned char>^ output_buffer = gcnew array<unsigned char>(16);
ICryptoTransform^ encryptor = AES->CreateEncryptor(AES->Key, AES->IV);
encryptor->TransformBlock(plainText, 0, plainText->Length, output_buffer, 0);
return output_buffer;
}
void from_base_256(unsigned char *y, int len, int s, char *x)
{
int i, m, n;
unsigned int c, d;
m = 16;
n = 0; c = 0;
for (;;)
{
while (m>0 && y[m - 1] == 0) m--;
d = 0;
for (i = m - 1; i >= 0; i--)
{
d = (d << 8) + y[i];
y[i] = d/s;
d %= s;
}
d += c + x[n]; c = 0;
if ((int)d >= s)
{
c = 1; x[n] = d - s;
}
else x[n] = d;
n++;
if (n >= len) break;
}
}
int to_base_256(char *x, int len, int s, unsigned char *y)
{
int i, j, m;
unsigned int c;
for (i = 0; i<16; i++)
y[i] = 0;
if (len == 0) return 0;
m = 1; y[0] = x[len - 1];
for (j = len - 2; j >= 0; j--)
{
c = x[j];
for (i = 0; i<m; i++)
{
c += (unsigned int)y[i] * s;
y[i] = c & 0xff;
c >>= 8;
}
if (c>0) { m++; y[m - 1] = c; }
}
return m;
}
int main(array<System::String ^> ^args)
{
int i, n;
//PLAINTEXT
char x[256];
x[0] = 1; x[1] = 4; x[2] = 2; x[3] = 5; x[4] = 6; x[5] = 9; x[6] = 8; x[7] = 7;
x[8] = 2; x[9] = 1; x[10] = 5; x[11] = 4; x[12] = 6; x[13] = 5; x[14] = 3; x[15] = 2;
unsigned int TL, TR;
TR = 0;
TL = 0;
int j;
char *left, *right;
unsigned char buff[16];
int l, r;
l = r = 16/2;
if (16 % 2 == 1) l++;
left = &x[0]; right = &x[l];
for (j = 0; j < 8; j++)
{
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("ROUND " + (j+1));
if (j % 2 == 0)
{
to_base_256(right, r, 10, buff);
unpack(TR^j, &buff[12]);
int size = sizeof(buff)/sizeof(*buff);
array<unsigned char>^ inputPlaintext = gcnew array<unsigned char>(size);
for (int i = 0; i < size; i++)
inputPlaintext[i] = buff[i];
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("INPUT");
for (int z = 0; z < size; z++)
System::Diagnostics::Debug::Write(inputPlaintext[z] + ",");
array<unsigned char>^ result = AES_encrypt_block(inputPlaintext);
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("AES ENCRYPTED");
for (int z = 0; z < size; z++)
System::Diagnostics::Debug::Write(result[z] + ",");
pin_ptr<unsigned char>buff = &result[0];
from_base_256(buff, l, 10, left);
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("afterFromBase256 - left");
for (int z = 0; z < sizeof(left)/sizeof(*left); z++)
System::Diagnostics::Debug::Write(left[z] + " , ");
}
else
{
to_base_256(left, l, 10, buff);
unpack(TL^j, &buff[12]);
int size = sizeof(buff)/sizeof(*buff);
array<unsigned char>^ inputPlaintext = gcnew array<unsigned char>(size);
for (int i = 0; i < size; i++)
inputPlaintext[i] = buff[i];
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("INPUT");
for (int z = 0; z < size; z++)
System::Diagnostics::Debug::Write(inputPlaintext[z] + ",");
array<unsigned char>^ result = AES_encrypt_block(inputPlaintext);
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("AES ENCRYPTED");
for (int z = 0; z < size; z++)
System::Diagnostics::Debug::Write(result[z] + ",");
pin_ptr<unsigned char>buff = &result[0];
from_base_256(buff, r, 10, right);
System::Diagnostics::Debug::WriteLine("");
System::Diagnostics::Debug::WriteLine("afterFromBase256 - right");
for (int z = 0; z < sizeof(right)/sizeof(*right); z++)
System::Diagnostics::Debug::Write(right[z] + " , ");
}
}
return 0;
}
सी # कंसोल आवेदन
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Numerics;
namespace BPS_ConsoleTest
{
class Program
{
static void Main(string[] args)
{
//integer array to hold the bytes of plaintext
int[] plaintext = new int[16] { 1, 4, 2, 5, 6, 9, 8, 7, 2, 1, 5, 4, 6, 5, 3, 2 };
byte[] key = new byte[16];
key[0] = 0x01; key[1] = 0x01; key[2] = 0x01; key[3] = 0x01; key[4] = 0x01; key[5] = 0x01; key[6] = 0x01; key[7] = 0x01;
key[8] = 0x01; key[9] = 0x01; key[10] = 0x01; key[11] = 0x01; key[12] = 0x01; key[13] = 0x01; key[14] = 0x01; key[15] = 0x01;
//Block Cipher - AES-128
AES AESEncrypt = new AES(key);
int bits = 128 - 32; //128 block for AES-128
//tweak
int tweak = 0; //64 bit user provided tweak value
int TR = 0; //left side of tweak
int TL = 0; //right side of tweak
int s = 10;
int w = 8; //recommended number of rounds
int BLOCK_SIZE = 16; //block size in bytes (16 = 128 bits for AES-128)
int b = 0; //s-integer input length
b = plaintext.Length;
//Split the tweak into right and left
//
TR = tweak % (1 << 32);
TL = (tweak - TR)/(1 << 32);
//Split the plaintext into left and right substrings
//
int j = 0;
int[] XR; //right substring
int[] XL; //left substring
int l; //length of left substring
int r; //length of right substring
if (b % 2 == 1) //b is odd
{
l = (b + 1)/2;
r = (b - 1)/2;
}
else //b is even
{
l = r = b/2;
}
XL = new int[l];
XR = new int[r];
for (int i = 0; i < l; i++)
XL[i] = plaintext[i];
j = 0;
for (int i = l; i <= l + r - 1; i++, j++)
XR[j] = plaintext[i];
//initialize left and right branches
BigInteger L = 0;
for (int i = 0; i < l; i++)
{
L += XL[i] * BigInteger.Pow(s, i);
}
BigInteger R = 0;
for (int i = 0; i < l; i++)
{
R += XR[i] * BigInteger.Pow(s, i);
}
byte[] initial_Lbytes = L.ToByteArray();
byte[] initial_Rbytes = R.ToByteArray();
int[] intitial_L = new int[l];
int[] intitial_R = new int[r];
foreach (byte bL in initial_Lbytes)
{
BigInteger num = new BigInteger(new byte[] { bL });
}
//8 Rounds
for (int i = 0; i < 8; i++)
{
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("ROUND " + (i + 1));
if (i % 2 == 0) //even
{
byte[] RBytes = R.ToByteArray();
byte[] inputPlaintext = new byte[16];
for (int k = 0; k < RBytes.Length; k++)
inputPlaintext[k] = RBytes[k];
inputPlaintext = INT2LE(TR^i, inputPlaintext);
System.Diagnostics.Debug.WriteLine("INPUT");
foreach (byte bb in inputPlaintext)
System.Diagnostics.Debug.Write(bb + ",");
byte[] t = AESEncrypt.Encrypt(inputPlaintext);
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("AES ENCRYPTED");
foreach (byte bb in t)
System.Diagnostics.Debug.Write(bb + ",");
BigInteger AESResult = new BigInteger(t);
BigInteger res = (L + AESResult) % BigInteger.Pow(s, l);
L = res;
}
else //odd
{
byte[] LBytes = L.ToByteArray();
byte[] inputPlaintext = new byte[16];
for (int k = 0; k < LBytes.Length; k++)
inputPlaintext[k] = LBytes[k];
inputPlaintext = INT2LE(TL^i, inputPlaintext);
System.Diagnostics.Debug.WriteLine("INPUT");
foreach (byte bb in inputPlaintext)
System.Diagnostics.Debug.Write(bb + ",");
byte[] t = AESEncrypt.Encrypt(inputPlaintext);
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("AES ENCRYPTED");
foreach (byte bb in t)
System.Diagnostics.Debug.Write(bb + ",");
BigInteger AESResult = new BigInteger(t);
BigInteger res = (R + AESResult) % BigInteger.Pow(s, r);
R = res;
}
}
BigInteger FINAL_R = R;
BigInteger FINAL_L = L;
}
public static byte[] INT2LE(Int32 data, byte[] arr)
{
byte[] b = arr;
b[12] = (byte)data;
b[13] = (byte)(((uint)data >> 8) & 0xFF);
b[14] = (byte)(((uint)data >> 16) & 0xFF);
b[15] = (byte)(((uint)data >> 24) & 0xFF);
return b;
}
}
public class AES : IBlockCipher
{
private byte[] _key;
public AES(byte[] key)
{
_key = key;
}
public byte[] Encrypt(byte[] input)
{
byte[] output_buffer = new byte[16];
using (AesManaged E = new AesManaged())
{
E.BlockSize = 128;
E.KeySize = 128;
E.Mode = CipherMode.ECB;
E.Key = _key;
E.Padding = PaddingMode.None;
//E.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = E.CreateEncryptor(E.Key, E.IV);
encryptor.TransformBlock(input, 0, 16, output_buffer, 0);
}
//return encrypted;
return output_buffer;
}
}
interface IBlockCipher
{
byte[] Encrypt(byte[] input);
}
}
बस एक साइड नोट के रूप में - यदि आप एन्क्रिप्शन का अध्ययन करने के लिए ऐसा कर रहे हैं, कोई समस्या नहीं है, लेकिन उत्पादन में एन्क्रिप्शन एल्गोरिदम के अपने कार्यान्वयन को रखने से सावधान रहें। भेद्यताएं पेश करना बहुत आसान है जो मूल कार्यान्वयन में मौजूद नहीं हैं, अक्सर नए पक्ष चैनल हमलों, लेकिन आपके द्वारा उपयोग की जाने वाली पुस्तकालयों में भी कमजोरियां। –
@ केविनकेन उन कुछ हमलों को हार्डवेयर तक पहुंच की आवश्यकता नहीं है जिस पर सादे पाठ का एन्क्रिप्शन किया गया था? – erotavlas
हां, कुछ करते हैं, लेकिन मैंने केवल उन उदाहरणों के रूप में उल्लेख किया है। अधिक महत्वपूर्ण विचार यह है कि आप * नहीं जानते * आप किस भेद्यता को पेश करते हैं। आपको अपने स्वयं के कोड, और आपके द्वारा उपयोग की जाने वाली किसी भी पुस्तकालय के पूर्ण विश्लेषण की आवश्यकता होगी। कार्यान्वयन के मुद्दे के कारण हुई भेद्यता के लिए एक उदाहरण हार्टबलेड था - और यह ओपनएसएसएल के विशेषज्ञों के साथ हुआ। –