安全中国首页 > 文章中心 > 商用保护技术
 
怎样攻破 RSA-1024的算法保护
更新时间:2008-2-8 0:23:30
责任编辑:阿loosen
热 点:
stasi的本机测试

测试环境:
硬件环境:p42.0G+256M(DDR 400)
系统环境:  WIN2000+SP4
软件环境:MASM6.exe编译

5.1  测试对象: Asprotect1.0

5.1.1测试代码
.586                                             
.MODEL FLAT,STDCALL
; ------------------------------------------------------
; Poorly coded brute forcer for Asprotect 1.0/1.11
;        by Amenesia//TKM!
; ------------------------------------------------------

include BruteAspro10.inc


.DATA

;..User friendly :).........................
solution  db "Seed =",0 
notf      db "- Nop -",0
hexstring db "0123456789ABCDEF",0
result    db "00000000",0

;..Brute-forcer............................
CurrentSeed dd 00000000h
MinSeed     dd 0398BBB73h
MaxSeed     dd 0FFFFFFFFh

;..N........................................
HighMod     dd 0EB1D4EADh


.CODE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

BruteForcer:

 mov eax, [MinSeed]
 
BruteForcer_loop:
 push eax
 mov [CurrentSeed], eax
 call RandInt
 or eax, 0C0000000h
 push eax
 call RandInt
 or eax, 0C0000000h
 pop ebx
 mul ebx
 sub edx, [HighMod]
 cmp edx, 2
 jbe SeedF
 pop eax
 inc eax
 cmp eax, [MaxSeed]
 je  SeedNotF
 jmp BruteForcer_loop
 
 
 SeedF:
 pop eax
 mov edi, (offset result+7)
Hex2ascii:
 mov ebx, eax
 and ebx, 0Fh
 mov  bl, [offset hexstring + ebx]
 mov  [edi], bl
 sub  edi, 1
 shr  eax, 4
 cmp  eax, 0
 jne  Hex2ascii
  
 call MessageBoxA,0,offset result,offset solution,0
 ret
 
SeedNotF:  
 call MessageBoxA,0,offset notf,offset solution,0
 ret

rand    proc near  
    mov  ecx, [CurrentSeed]
    imul  ecx, 343FDh
    add      ecx, 269EC3h
    mov  [CurrentSeed], ecx
    mov  eax, ecx
    shr  eax, 10h
    and  eax, 7FFFh
    retn
rand    endp 
  
 RandInt    proc near  

    mov  edi, 60
    mov  ecx, [CurrentSeed]    
highbyte:  
    imul  ecx, 343FDh
    add      ecx, 269EC3h
    dec edi
    jnz highbyte
    mov  [CurrentSeed], ecx  
      
    xor  esi, esi
    mov  edi, 4
build_int:        
    call  rand
    shl  esi, 8
    add  esi, eax
    dec  edi
    jnz  build_int
    mov  eax, esi
    retn
RandInt    endp

end BruteForcer
ends

5.1.2 测试结果
用时:3.12秒
 

D= l8F1EGKSQWCw9Et5klCpkm9/TIQFw0xOxibd+bQNndzGYoIX
4PmHXcdZtN3VWRQfuYS/cLeEf0i+kG3Cd7kaqKCkBO3xiAFgZMf
vW8D+bov+AfjDICITq5/Lhex7PykLGtUNnH8LSsmIDSWqldwX3Q
9o8U4HcJSjSJIfS4bumc=


5.2  测试对象:Asprotect1.1c

5.2.1测试代码:
.586                                             
.MODEL FLAT,STDCALL
; ------------------------------------------------------
; Poorly coded brute forcer for Asprotect 1.11c
;          by Amenesia//TKM!
; ------------------------------------------------------

include BruteAspro111c.inc


.DATA

;..User friendly :).........................
solution  db "_rand() =",0 
notf      db "- Nop -",0
hexstring db "0123456789ABCDEF",0
result    db "00000000",0

;..Brute-forcer............................
CurrentSeed dd 00000000h

MinSeed     dd  00000000h
MaxSeed     dd  00007FFFh

;..N........................................
Mod_p1 dd 0C7D6E57Ah
Mod_p2 dd 00D1C3A97h
Mod_p3 dd 052618FB4h
Mod_p4 dd 097A6E4D1h

.CODE
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
BruteForcer:
 mov eax, [MinSeed]
BruteForcer_loop:
 push eax
 mov [CurrentSeed], eax
 call RandInt
 mov ebx, eax
 or  eax, 0C0000000h 
 mov ebp, eax
 mov edx, [Mod_p1]
 mov eax, [Mod_p2]
 cmp ebp, edx
 jb nextseed  
 div ebp
 mov esi, eax
 mov edi, edx
big_mul:
 mov eax, ebx
 mul esi
 mov ecx, edx
 add edx, eax
 adc ecx, 0 
 cmp edi, ecx
 jb too_big
 ja sub_big
 cmp [Mod_p3], edx
 jb too_big
 ja sub_big
cmp [Mod_p4], eax
 jb too_big
 jae sub_big  
too_big:
 dec esi
 ;add edi, ebp
 ;jmp big_mul
 sub ecx, ebp 
sub_big:
 push [Mod_p4]
 push [Mod_p3] 
 sub [Mod_p4], eax
 sbb [Mod_p3], edx
 sbb edi, ecx
 mov eax, [Mod_p3]
 mov edx, edi 
 pop [Mod_p3]
 pop [Mod_p4] 
 div ebp
 mov ebp, edx
 mov edi ,eax
 mul ebx
 cmp edx, ebp
 jb nocarry
 dec edi
nocarry:
 or edi, 0C0000000h
 and esi, 0FFFFFFFEh
 and edi, 0FFFFFFFEh 
 cmp esi, edi
 je  SeedF
nextseed:
 pop eax
 inc eax
 cmp eax,[MaxSeed ]
 je SeedNotF
 jmp BruteForcer_loop
SeedF:
 pop eax
 call RandInt 
 mov edi, (offset result+7) 
Hex2ascii:
 mov ebx, eax
 and ebx, 0Fh
 mov  bl, [offset hexstring + ebx]
 mov  [edi], bl
 sub  edi, 1
 shr  eax, 4
 cmp  eax, 0
 jne  Hex2ascii 
 call MessageBoxA,0,offset result,offset solution ,0
 ret 
SeedNotF:  
 call MessageBoxA,0,offset notf ,offset solution,0
 ret
rand    proc near  
    mov  eax, [CurrentSeed]
    and  eax, 7FFFh
    retn
rand  endp   
 RandInt    proc near        
    xor  esi, esi
    mov  edi, 4
build_int:        
    call rand
    shl  esi, 8
    add  esi, eax
    dec  edi
    jnz  build_int
    mov  eax, esi
    retn
RandInt    endp 
end BruteForcer
ends

5.2.2 测试结果
用时:0.98秒
 
D = HV/nbSNxR14Tvhm4bHRVey+U+qdbHQk8Q+BPfBrY
qZYMa14KmBhtGX4flkK+gVoGGX23485UMFwdxMMux5Aw
DtEsU+ZTzlQmvNX5zEuDRVg/1jZJGc7NIBltCVy+sOt+
iVqzBnopoHPQHrNGzDkr/615Ch40ns4iIWp3i7PbRs

6 译者(stasi)的话

作为一个算法爱好者,对blowfish前辈从exetool转来的<<How break RSA-1024 ?>>文章也甚是有兴趣,所以翻译过来大家研究。
我主要是想说说自己对这次攻破算法保护的看法:
以前常说RSA的安全性就依赖于大数的分解,通过密钥数位的增加就能在一定程度上使得算法是很安全的,这是在数学领域正确,但从这篇文章来看,把算法保护运用到软件设计上又是由很多需要注意的地方了。Asprotect 1.0/1.1/1.11c的算法被攻破,其主要原因就是Seed的估计不足造成的。我们来看一下Asprotect 1.0/1.1/1.11c在选取大素数p和q时所用的代码:
unsigned long _rand()  //基本数的生成
{
Seed *= 214013;     
Seed += 2531011;
return( ((Seed >> 16) & 0x7FFF) );
}
unsigned long RandInt() //整数随机数的生成
{
for(i=0;i<4;i++) { rval = ((rval << 8) +_ rand()); }
return(rval);
}
Seed = ( time() + ThreadId()) xor TickCount();  //seed的计算公式
for(ri=0;ri<16;ri++) { BigNumber1[ri] = RandInt(); }
BigNumber1[ri] = BigNumber1[ri] xor C0000000h;
P= nextPrime(BigNumber1);
for(ri=0;ri<16;ri++) { BigNumber2[ri] = RandInt(); }
BigNumber2[ri] = BigNumber2[ri] xor C0000000h;
Q= nextPrime(BigNumber2);

主要关注( time() + ThreadId()) xor TickCount(),看似有了( time() + ThreadId()),结果似乎是一个随机的数值,但由于( time() + ThreadId()) xor TickCount()在计算的时候有计算机自行完成,且计算的函数取值固定,就导致 GetTickCount and time()在计算随机数的时候基本是保持在time()值左右,意外的导致了计算所的到的数值并不是一个很随机的数,用老罗的话就是“伪随机数”,它是在一个数值段内的一个随机数,而大素数p和q就是通过这个数值计算得到的,这就大大限制了大素数p和q选取可能,使得穷举成为了可能。我们都知道一旦大素数p和q被知道之后,RSA就毫无保护意义可言,通过p和q计算就能得到得到私钥d,然后把密文分组得到的数值,计算他的d次方,并与n取模就是原始数据了。
本人万分感慨原作者对加密算法的理解,并不是冒然尝试分解n的值,而是仔细分析了算法的本质要素,找到了RSA-1024算法和软件Asprotect 1.0/1.1/1.11c两者相结合的弱点。这也揭示了数学意义上的随机数和软件编程上的随机数的区别,这也许也将在以后对其他算法攻破有很大的指导意义。

7 译者(stasi)对算法的改进想法:

但就RSA-1024本身而言,不是什么问题,并不需要怀疑它的强度问题,因为在其他数据保护方面,要知道产生大素数的函数并不时很简单的事!我所想到的改进方法,供大家研究:
1)Asprotect 如果还想使用RSA-1024算法的话,只要注意对产生大素数的随机种子数的选取就可以了,不使用time(),而是尝试利用其他的随机数,例如磁盘文件大小,文件建立时间等随机数,混沌或分形理论。
2)即使使用time()函数也要将随机池放大,覆盖有一定大范围的数据段,使穷举变得困难。
3)把算法验证放在网络上,使得攻破者不能得到大素数p和q的生成方法,要知道无畏的穷举并不是一个理想的办法:)

stasi
2005.4.13 上海

·上一篇: 破解用Vboxs420.dll加密的WebDrive 2.2
·下一篇: 暂时空缺
 
相关文章
48小时热门文章
 
48小时热门软件
48小时热门动画