其他
微型加密算法实现及逆向分析
本文为看雪论坛精华文章看雪论坛作者ID:丿feng
这篇文章主要是对TEA系列算法的简单分析,本人原创,另外对于文中引用的图片和些许代码,若有侵权,务必联系本人。
1、关于TEA系列算法
2、加解密实现
1. TEA加解密实现
void encrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
for (size_t i = 0; i < 32; i++) {
sum += delta;
l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
}
v[0] = l;
v[1] = r;
}
void decrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
sum = delta *32;
for (size_t i = 0; i < 32; i++) {
r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
sum -= delta;
}
v[0] = l;
v[1] = r;
}
int main(int argc, char const *argv[])
{
//test
unsigned int v[2]={1,2},key[4]={1,2,3,4};
printf("%u,%u\n",v[0],v[1]);
encrypt(v,key);
printf("%u,%u\n",v[0],v[1]);
decrypt(v,key);
printf("%u,%u\n",v[0],v[1]);
return 0;
}
2. XTEA加解密实现
void encrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
for (size_t i = 0; i < 32; i++) {
l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
sum += delta;
r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = l;
v[1] = r;
}
void decrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
sum = delta * 32;
for (size_t i = 0; i < 32; i++) {
r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
sum -= delta;
l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
}
v[0] = l;
v[1] = r;
}
int main(int argc, char const *argv[])
{
//test
unsigned int v[2]={1,2},key[4]={1,2,3,4};
printf("%u,%u\n",v[0],v[1]);
encrypt(v,key);
printf("%u,%u\n",v[0],v[1]);
decrypt(v,key);
printf("%u,%u\n",v[0],v[1]);
return 0;
}
3. XXTEA加解密实现
bool btea(unsigned int* v, int n, unsigned int* k) {
unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x9e3779b9;
unsigned int p, q;
if (n > 1) { /* Coding Part */
q = 6 + 52 / n;
while (q-- > 0) {
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
y = v[p + 1], z = v[p] += MX;
y = v[0];
z = v[n - 1] += MX;
}
return 0;
} else if (n < -1) { /* Decoding Part */
n = -n;
q = 6 + 52 / n;
sum = q * DELTA;
while (sum != 0) {
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
z = v[p - 1], y = v[p] -= MX;
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
}
return 0;
}
return 1;
}
int main(int argc, char const* argv[]) {
// test
unsigned int v[2] = {1, 2}, key[4] = {1, 2, 3, 4};
printf("%u,%u\n", v[0], v[1]);
btea(v, 2, key);
printf("%u,%u\n", v[0], v[1]);
btea(v, -2, key);
printf("%u,%u\n", v[0], v[1]);
return 0;
}
>>>>
3、XXTEA逆向分析
{
v3 = a3;
v4 = a2;
v5 = *a1;
v43 = a2;
if ( a2 > 1 )
{
v6 = a2 - 1;
v7 = &a1[a2 - 1];
v8 = 0;
v9 = *v7;
v10 = ((a2 - 4) & 0xFFFFFFFE) + 2;
v45 = 0x9E3779B9 * (52 / a2) - 0x4AB325AA;
do
{
v8 -= 0x61C88647;
v11 = v8 >> 2;
if ( v43 <= 3 )
{
v14 = 0;
}
else
{
v12 = *a1;
v13 = a1;
v14 = 0;
do
{
v15 = v13[1];
v13 += 2;
v16 = (v9 ^ *(_DWORD *)(v3 + 4LL * (((unsigned __int8)v14 ^ (unsigned __int8)v11) & 3))) + (v15 ^ v8);
v17 = v14 + 1;
v14 += 2;
v18 = v12 + ((((v9 >> 5) ^ 4 * v15) + ((v15 >> 3) ^ 16 * v9)) ^ v16);
v12 = *v13;
*(v13 - 2) = v18;
v9 = v15
+ (((4 * v12 ^ (v18 >> 5)) + (16 * v18 ^ (v12 >> 3))) ^ ((v12 ^ v8)
+ (v18 ^ *(_DWORD *)(v3
+ 4LL
* (((unsigned __int8)v11 ^ v17) & 3)))));
*(v13 - 1) = v9;
}
while ( v10 != v14 );
}
v19 = &a1[v14];
do
{
v20 = v19[1];
v21 = v11 ^ v14++;
++v19;
v22 = *(v19 - 1)
+ (((v9 ^ *(_DWORD *)(v3 + 4LL * (v21 & 3))) + (v20 ^ v8)) ^ ((16 * v9 ^ (v20 >> 3)) + ((v9 >> 5) ^ 4 * v20)));
*(v19 - 1) = v22;
v9 = v22;
}
while ( v6 > v14 );
v9 = *v7
+ (((v22 ^ *(_DWORD *)(v3 + 4LL * (((unsigned __int8)v6 ^ (unsigned __int8)v11) & 3))) + (*a1 ^ v8)) ^ ((4 * *a1 ^ (v22 >> 5)) + (16 * v22 ^ ((unsigned int)*a1 >> 3))));
*v7 = v9;
}
while ( v8 != v45 );
return 0LL;
}
result = 1LL;
if ( a2 < -1 )
{
v24 = -a2;
v25 = 0x9E3779B9 * (52 / v24 + 6);
if ( v25 )
{
v26 = &a1[v24 - 1];
v27 = ~v4;
v44 = &a1[~v4];
v28 = ~v4 - 2 - ((~v4 - 3) & 0xFFFFFFFE);
do
{
v29 = v25 >> 2;
if ( v27 <= 2 )
{
v31 = v27;
}
else
{
v30 = v44;
v31 = v27;
v32 = *v44;
do
{
v33 = *(v30 - 1);
v30 -= 2;
v34 = v32;
v32 = *v30;
v35 = ((v5 ^ v25) + (v33 ^ *(_DWORD *)(v3 + 4LL * (((unsigned __int8)v31 ^ (unsigned __int8)v29) & 3)))) ^ ((4 * v5 ^ (v33 >> 5)) + ((v5 >> 3) ^ 16 * v33));
v36 = v31 - 1;
v31 -= 2;
v37 = v34 - v35;
v38 = *v30;
v30[2] = v37;
v5 = v33
- (((16 * v38 ^ (v37 >> 3)) + ((v32 >> 5) ^ 4 * v37)) ^ ((v32 ^ *(_DWORD *)(v3
+ 4LL
* (((unsigned __int8)v29 ^ v36) & 3)))
+ (v25 ^ v37)));
v30[1] = v5;
}
while ( v28 != v31 );
}
v39 = &a1[v31];
do
{
v40 = *(v39 - 1);
--v39;
v5 = v39[1]
- (((v5 ^ v25) + (v40 ^ *(_DWORD *)(v3 + 4LL * (((unsigned __int8)v29 ^ (unsigned __int8)v31) & 3)))) ^ (((v5 >> 3) ^ 16 * v40) + ((v40 >> 5) ^ 4 * v5)));
v39[1] = v5;
--v31;
}
while ( v31 );
v41 = *a1
- (((((unsigned int)*v26 >> 5) ^ 4 * v5) + (16 * *v26 ^ (v5 >> 3))) ^ ((*(_DWORD *)(v3 + 4LL * (v29 & 3)) ^ *v26)
+ (v25 ^ v5)));
v42 = v25 == 0x9E3779B9;
v25 += 0x61C88647;
v5 = v41;
*a1 = v41;
}
while ( !v42 );
}
return 0LL;
}
return result;
}
using namespace std;
// -lcrypto
string MD5(const string& src) {
MD5_CTX ctx;
string md5_string;
unsigned char md[16] = {0};
char tmp[33] = {0};
MD5_Init(&ctx);
MD5_Update(&ctx, src.c_str(), src.size());
MD5_Final(md, &ctx);
for (int i = 0; i < 16; ++i) {
memset(tmp, 0x00, sizeof(tmp));
sprintf(tmp, "%02X", md[i]);
md5_string += tmp;
}
return md5_string;
}
string aaa(unsigned int* v) {
string str;
for (size_t i = 0; i < 2; i++) {
for (size_t j = 0; j < 8; j += 2) {
unsigned char cur = v[i] & 0xff;
str += ((cur & 0xf0) >> 4) < 10 ? (((cur & 0xf0) >> 4) + 0x30)
: (((cur & 0xf0) >> 4) + 0x57);
str += (cur & 0x0f) < 10 ? ((cur & 0x0f) + 0x30) : ((cur & 0x0f) + 0x57);
v[i] >>= 8;
}
}
return str;
}
bool btea(unsigned int* v, int n, unsigned int* k) {
unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x9e3779b9;
unsigned int p, q;
if (n > 1) { /* Coding Part */
q = 6 + 52 / n;
while (q-- > 0) {
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
y = v[p + 1], z = v[p] += MX;
y = v[0];
z = v[n - 1] += MX;
}
return 0;
} else if (n < -1) { /* Decoding Part */
n = -n;
q = 6 + 52 / n;
sum = q * DELTA;
while (sum != 0) {
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
z = v[p - 1], y = v[p] -= MX;
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
}
return 0;
}
return 1;
}
int main() {
// 55 7e 79 70 78 36 xx 02
unsigned int t[2] = {0x70797e55, 0x02003678};
unsigned int v[2] = {0, 0};
unsigned int key[4] = {0xE0C7E0C7, 0xC6F1D3D7, 0xC6D3C6D3, 0xC4D0D2CE};
string flagmd5 = "5F8243A662CF71BF31D2B2602638DC1D";
for (unsigned long long i = 0x0; i <= 0xff; i += 0x1) {
v[0] = t[0];
v[1] = t[1] | (i << 16);
string flag = "";
flag += "rctf{";
btea(v, 2, key);
flag += aaa(v);
flag += "}";
cout << flag << endl;
if (MD5(flag) == flagmd5) {
cout << "success!" << endl;
cout << flag << endl;
return 0;
}
}
return 0;
}
4、TX TEA魔改算法
>>>>
总结
6、附件
TEA系列算法源码
2019RCTF babyre
7、参考文献
Tiny Encryption Algorithm XTEA XXTEA TEA、XTEA、XXTEA加密解密算法 加密与解密第四版—TEA算法
- End -
看雪ID:丿feng
https://bbs.pediy.com/user-809191.htm
*本文由看雪论坛 丿feng 原创,转载请注明来自看雪社区
推荐文章++++
﹀
﹀
﹀
进阶安全圈,不得不读的一本书
﹀
﹀
﹀