这个消息拆分如何工作?

时间:2013-07-17 18:45:00

标签: cryptography rsa

我最近一直试图在编译代码中对各种加密算法进行逆向工程,我发现了这段代码。它是RSA算法的一部分。我注意到密钥大小太小,无法加密/解密它应该的数据(在这种情况下为int),因此代码将消息拆分为两部分,然后加密/解密每个,然后求和他们在一起。我已经拉出了拆分和加入消息的代码片段,并进行了实验。看来它使用的数值取决于n模数。那么,这个方案究竟是什么,它是如何运作的?

uint n = 32437;
uint origVal = 12345;
uint newVal = 0;

for (int i = 0; i < 2; ++i)
{
    ulong num = (ulong)origVal * 43827549;
    //uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
    uint num2 = (origVal + (uint)(num >> 32)) / 32768;
    origVal -= num2 * n;                
    // RSA encrypt/decrypt here
    newVal *= n;
    newVal += origVal;
    origVal = num2;
}

// Put newVal into origVal, to reverse
origVal = newVal;
newVal = 0;

for (int i = 0; i < 2; ++i)
{
    ulong num = (ulong)origVal * 43827549;
    //uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
    uint num2 = (origVal + (uint)(num >> 32)) / 32768;
    origVal -= num2 * n;                
    // RSA encrypt/decrypt here
    newVal *= n;
    newVal += origVal;
    origVal = num2;
}

注意:应用的操作似乎是对称的。

1 个答案:

答案 0 :(得分:1)

在使用origVal的各种值之后,我发现for循环之后的前三行只是一个除法,紧接着是一个模运算之后的行。行

ulong num = (ulong)origVal * 43827549;
//uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
uint num2 = (origVal + (uint)(num >> 32)) / 32768;

转换为

uint valDivN = origVal / n;

origVal -= num2 * n;

origVal = origVal % n;


所以for循环中的最终代码如下所示:

uint valDivN = origVal / n;
origVal = origVal % n;
// RSA encrypt/decrypt here
newVal*= n;
newVal+= origVal;
origVal = valDivN;


分析

此代码通过获取原始值的模数,转换它,然后将其乘以n,并将前一个商的转换加到结果上来拆分值。行uint valDivN = origVal / n;newVal*= n;形成逆操作。您可以将输入消息视为具有两个“框”。在循环运行之后,您将转换后的值放在相反的“框”中。当消息被解密时,“框”中的两个值被反向变换,并将它们放在“框”中的原始位置。除数为n的原因是保持值在n下加密/解密,因为使用RSA加密的最大值不大于n。不可能解密错误的值,因为代码处理打包的消息并提取在解密之前应该解密的部分。循环只运行两次,因为商不可能超过int的大小(因为输入是int)。