Skype's encryption procedure partly exposed
Skype Logo Developer Sean O'Neill, famous in cryptographic circles for designing the EnRUPT hash algorithm, has released an open source Skype library that emulates the modified version of the RC4 encryption algorithm used by Skype. Skype chose to modify key generation for the stream cipher to make its product incompatible with other IM clients and ensure that it remained a closed system. However, initial analysis suggests that O'Neill's publication does not mean that Skype's encryption can be considered 'cracked'. Further study will be needed to determine whether key expansion and initialisation vector generation are secure.
Because Skype has not released details of its encryption procedures, for years researchers have been trying and failing to reverse engineer the company's encryption. What is clear is that Skype uses a variety of encryption procedures. AES-256 is used to communicate with Skype's login server, SMS/event server and search servers. Supernodes and clients use the modified version of RC4 for the actual communication.
No further information is currently available – O'Neill's website, on which he announced his breakthrough, is currently offline. Even the Skype Library RC4 v1.108 download is currently offline. O'Neill has promised further details, but not until December, when he intends to present his findings at the Chaos Communication Congress in Berlin (27C3).
Until then, interested users can examine the code and use it for test purposes. Commercial usage is currently permissible only after consultation with O'Neill.
first:
The sophisticated encryption code used by Skype to protect its network has been exposed by cryptography expert Sean O'Neil.
O'Neil believes that the code is already being exploited by Skype spammers.
Skype's encryption code, based on a cipher called RC4, is used by the VoIP service provider to protect its clients and servers being attacked by hackers and spammers, as well as preventing third parties from creating their own IM clients using Skype's network.
In a statement, Sean O'Neil, said: “Skype enjoyed selling the world security by obscurity. We must admit, really good obscurity. I mean, really really good obscurity. So good that almost no one has been able to reverse engineer it out of the numerous Skype binaries.”
The cryptographer has provided a link to a C Library which is the clone of the "obfuscated Skype RC4 key expansion algorithm" used by Skype to secure its network.
O'Neil also says that he released the open source code for research and educational purposes only.
Read more: http://www.itproportal.com/2010/07/09/skype-encryption-cracked/#ixzz1vmVvnZzk
很老的Skype版本(可能是2.x)上 进行TCP报文RC4解密过程中,生成RC4扩展密钥时,只用到了一个来自TCP报文的4字节参数作为生成扩展密钥函数的入参,但在新版本(4.x)上, 这一算法行不通了。
新版本上生成RC4扩展密钥用到了两个入参:4字节参数和一个0x30字节的参数。
RC4密钥扩展时,4字节参数用来初始化扩展密钥0x100(256),然后用0x30字节的参数对初始化的扩展密钥进行一系列变型,从而得到最终的扩展密钥(初始扩展密钥长度为0x100(256)+2,初始扩展密钥的末尾两字节为0x00),用该密钥来解密TCP RC4密文即可得到RC4明文(也就是AES-256密文,再经过AES-256解密之后就最终得到明文)。
以前老版本Skype的TCP报文加密是基于TCP RC4,而新版本Skype的TCP报文加密有所变化,貌似DH-384 based TCP RC4。
RC4算法介绍
RC4加密算法Ron Rivest(非常有名的非对称加密算法RSA三巨头之一)在1987年设计的,密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。该算法的速度可以达到DES加密的10倍左右,且具有很高级别的非线性。RC4起初是用于保护商业机密的。但是在1994年9月,它的算法被发布在互联网上,也就不再有什么商业机密了。RC4也被叫做ARC4(Alleged RC4——所谓的RC4),因为RSA从来就没有正式发布过这个算法。
备注:RC4是对称密钥加密算法,而RSA是非对称的加密算法。由于RC4算法加密是采用的xor,所以,一旦子密钥序列出现了重复,密文就有可能被破解。那么,RC4算法生成的子密钥序列是否会出现重复呢?由于存在部分弱密钥,使得子密钥序列在不到100万字节内就发生了完全的重复,如果是部分重复,则可能在不到10万字节内就能发生重复,因此,推荐在使用RC4算法时,必须对加密密钥进行测试,判断其是否为弱密钥。根据目前的分析结果,没有任何的分析对于密钥长度达到128位的RC4有效,所以,RC4是目前最安全的加密算法之一。
RC4算法介绍
RC4加密算法Ron Rivest(非常有名的非对称加密算法RSA三巨头之一)在1987年设计的,密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。该算法的速度可以达到DES加密的10倍左右,且具有很高级别的非线性。RC4起初是用于保护商业机密的。但是在1994年9月,它的算法被发布在互联网上,也就不再有什么商业机密了。RC4也被叫做ARC4(Alleged RC4——所谓的RC4),因为RSA从来就没有正式发布过这个算法。
备注:RC4是对称密钥加密算法,而RSA是非对称的加密算法。由于RC4算法加密是采用的xor,所以,一旦子密钥序列出现了重复,密文就有可能被破解。那么,RC4算法生成的子密钥序列是否会出现重复呢?由于存在部分弱密钥,使得子密钥序列在不到100万字节内就发生了完全的重复,如果是部分重复,则可能在不到10万字节内就能发生重复,因此,推荐在使用RC4算法时,必须对加密密钥进行测试,判断其是否为弱密钥。根据目前的分析结果,没有任何的分析对于密钥长度达到128位的RC4有效,所以,RC4是目前最安全的加密算法之一。
说白了就是调用两次相同的方法,就会将第一加密的数据还原成原始数据,这里的原始数据长度和私钥很重要。
#include<iostream>
#include<cstring>
using namespace std;
void crypt(char cipher[]);///解密过程函数,根据输入密钥再一次生成密钥流
void main()
{
cout<<"**************************RC4加解密程序**************************"<<endl;
cout<<"****************************欢迎使用*****************************"<<endl;
char choose1,choose2;
do{
int s[256],t[256];
char k[256];/用户输入的密钥
char plaintext[1024],ciphertext[1024];
cout<<"输入密钥:";
cin>>k;
for(int i=0;i<256;i++)//给字节状态矢量和可变长的密钥数组赋值
{
s[i]=i;
t[i]=k[i%strlen(k)];
}
int j=0;
for(int i=0;i<256;i++) //使用可变长的密钥数组初始化字节状态矢量数组s
{
int temp;
j=(j+s[i]+t[i])%256;
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
cout<<"/n输入要加密的字符串:"<<endl;
cin>>plaintext;
int m,n,key[256],q;
m=n=0;
int i;
cout<<"/n得到密文:"<<endl;
for(i=0;i<strlen(plaintext);i++)/由字节状态矢量数组变换生成密钥流并对明文字符进行加密
{
int temp;
m=(m+1)% 256;
n=(n+s[n])% 256;
temp=s[m];
s[m]=s[n];
s[n]=temp;
q=(s[m]+s[n])%256;
key[i]=s[q];
ciphertext[i]=plaintext[i]^key[i];
cout<<ciphertext[i];
}
ciphertext[i]='/0';
cout<<endl;
/*cout<<"/n密钥流是:";
for(int i=0;i<strlen(plaintext);i++)
cout<<key[i]<<" ";
cout<<endl;*/
//
/
//解密
cout<<"/n是否对上面的密文进行解密?(y/n)";
cin>>choose2;
while(choose2=='y'||choose2=='Y')
{
/*cout<<"/n解密后所得到的明文是:"<<endl;
for(int p=0;p<strlen(plaintext);p++)/通过加密时所记录的密钥流对加密密文进行解密
{
plaintext[p]=ciphertext[p]^key[p];
cout<<plaintext[p];
}
cout<<endl;*/
crypt(ciphertext);///解密过程函数
choose2='n';
}
cout<<endl;
cout<<"/n是否希望继续使用程序?(y/n)";
cin>>choose1;
}while(choose1=='y'||choose1=='Y');
cout<<"/n****************************程序结束*****************************"<<endl<<endl;
system("pause");
}
/
///
//解密函数,密钥流的生成与加密相同
void decrypt(char cipher[])
{
int s[256],t[256];
char k[256];/用户输入的密钥
char plaintext[1024];
cout<<"/n输入密钥:";
cin>>k;
for(int i=0;i<256;i++)//给字节状态矢量和可变长的密钥数组赋值
{
s[i]=i;
t[i]=k[i%strlen(k)];
}
int j=0;
for(int i=0;i<256;i++) //使用可变长的密钥数组初始化字节状态矢量数组s
{
int temp;
j=(j+s[i]+t[i])%256;
temp=s[i];
s[i]=s[j];
s[j]=temp;
}
int m,n,key[256],q;
m=n=0;
int i;
cout<<"/n解密后所得到明文是:"<<endl;
for(i=0;i<strlen(cipher);i++)/由字节状态矢量数组变换生成密钥流并对密文字符进行解密
{
int temp;
m=(m+1)% 256;
n=(n+s[n])% 256;
temp=s[m];
s[m]=s[n];
s[n]=temp;
q=(s[m]+s[n])%256;
key[i]=s[q];
plaintext[i]=cipher[i]^key[i];
cout<<plaintext[i];
}
cout<<endl;
/*cout<<"/n密钥流是:";
for(int i=0;i<strlen(cipher);i++)
cout<<key[i]<<" ";*/
}