我现在要创建一个可以重新加密任意数据的算法。
经过一些工作,我设法大大减少了解密过程的代码库。它是这样工作的:
BigUnsigned hash_func(BigUnsigned serial, BigUnsigned running_value, BigUnsigned encrypt_key)
{
return (serial * running_value) - (((serial * running_value) / encrypt_key) * encrypt_key);
}
void do_the_thing()
{
BigUnsigned key1 = hash_func(buSerial, buSerial, buEncryptKey);
BigUnsigned key2 = hash_func(buSerial, key1, buEncryptKey);
BigUnsigned result = 1;
int key_select = 0;
unsigned int weird_number = 0xc3530000;
for(int i = 0; i < 8; ++i, weird_number *= 4){
result = hash_func(result, result, buEncryptKey);
result = hash_func(result, result, buEncryptKey);
if(weird_number >> 30){
key_select++;
if(key_select < 3){
result = hash_func(result, key2, buEncryptKey);
}else{
result = hash_func(result, buSerial, buEncryptKey);
if(key_select == 4){
key_select = 0;
}
}
}
}
}
和buSerial
都是16个无符号整数(512位)。我不知道如何创建一个算法,以此来加密新数据。我的问题是key2是从我事先不知道的最终结果中生成的。我正在使用此BigInt库
#1 楼
您是否还有其他信息,特别是buEncryptKey的一个或两个示例?那是素数吗?我问的原因是:您的
hash_func
是模函数,它计算(serial*running_value) % encrypt_key
。这就是key1 = serial^2%encrypt_key
和key2 = serial*(serial^2%encrypt_key)%encrypt_key = serial^3 % encrypt_key
。多项式模质数通常用于CRC计算或Fletcher的校验和中。循环的其余部分根据
(result^4 % encrypt_key)
中的某些位计算result*(serial^3) % encrypt_key
,然后计算(result*serial % encrypt_key)
或weird_number
。但是,您的key_select似乎有点混乱-您能否确保以这种方式计算key_select,而不仅仅是
(weird_number >> 30) & 0x03
? weird_number
在循环中的处理方式将使其在每一轮中检查2位(与4的乘法相符)是合乎逻辑的,我希望weird_number中的2位可用于选择您的其中一个if-else案件;现在在您的代码中,一次使用2位weird_number没有意义。 (此外,不要将较高的位屏蔽掉也没有意义,但是由于weird_number只是2字节整数,因此每次移位都会被丢弃)。一旦您正确计算函数的数学运算,您也许可以在互联网上找到它,或者math.stackexchange.com或crypto.stackexchange.com的人们可能有一个使用此算法的指针,以及如何创建一个匹配反向功能。
UPDATE
在今天工作中一个完全不相关的问题上,我检查了内容<两个不同的SSL客户端证书。其中之一说:模数
(大十六进制数),指数:0xbf0453。另一个表示:模量
(不同的大十六进制数),指数:0xcd01b7。然后我想到了你的
weird_number
,有了一个主意。然后我用google搜索了rsa算法。现在,我想我知道发生了什么。
rant>
来自Wikipedia的关于签名消息的信息使用RSA:
当鲍勃收到签名的消息时,他将签名提高到e的幂(模n),然后将所得的哈希值与消息的实际哈希进行比较。值。
这正是您的算法正在执行的操作。通过在每个循环中计算x ^ 4,然后根据指数的2位,将x或x ^ 3作为因数,可以对数学进行一点优化。这似乎是蒙哥马利阶梯技术的一种变体,它一次使用2位而不是1位。
e
是您的weird_number
(50003,仅使用了高16位),而n
是您的encrypt_key
。 (您可能希望让BigInteger库计算serial^50003 % encrypt_key)
并将结果与“纯文本数据”进行比较,以确保我是正确的,但实际上并没有进行检查。) ,则需要使用维基百科同一段落中的签名算法:Alice希望向Bob发送已签名的消息。她可以使用自己的
私钥来这样做。她生成消息的哈希值,将其提升为d的幂(模n)[...],并将其作为消息的
“签名”附加。
要计算输入,您需要
n
(您有)和d
(您没有)。要计算d
,需要将n
分解为两个生成的质数(p
,q
),其中n=pq
。这符合Wolfram Alpha的说法,即n
不是素数,但不幸的是,很难找到这些数字-毕竟,该算法被设计为不可破解的。但是,512位不再是最新技术,crypto.stackexchange.com的人说,对512位数字进行因式分解今天已经很可行。有更多的时间实现目标。很抱歉提供坏消息。
评论
谢谢您的帮助。 Wolfram alpha报告ecryptKey不是素数。 key_select确实不是原始的。生成的原始反汇编非常难看,我求助于一些捷径。
–埃里克
15年2月22日在13:08
serial ^ 50003非常长。我看到了一个用于该特定程序的软件,该软件将对新信息进行加密,这些新信息随后将被该程序正确解密(如果您知道我的意思)。也许我忽略了简化过程中的某些内容。
–埃里克
2015年2月24日21:00
serial ^ 50003很长,是真的。但您只需要(serial ^ 50003)%encrypt_key。举一个简单的例子,假设您要计算(7 ^ 11)%5。这等于((7 ^ 3)*(7 ^ 3)*(7 ^ 3)*(7 ^ 2))%5。但这也等于((((7 ^ 3)%5)*((7 ^ 3)%5)*((7 ^ 3)%5)*((7 ^ 2)%5))%5-在每一步之后取余数会使数字小得多,并且不会改变结果。这基本上就是您反汇编的算法。
–贡特拉姆·布洛姆
2015年2月24日在21:11