椭圆曲线加密分析FLEXLM ECC问答.docx
- 文档编号:2295045
- 上传时间:2023-05-03
- 格式:DOCX
- 页数:45
- 大小:39.90KB
椭圆曲线加密分析FLEXLM ECC问答.docx
《椭圆曲线加密分析FLEXLM ECC问答.docx》由会员分享,可在线阅读,更多相关《椭圆曲线加密分析FLEXLM ECC问答.docx(45页珍藏版)》请在冰点文库上搜索。
椭圆曲线加密分析FLEXLMECC问答
标题:
【原创】椭圆曲线加密分析:
FLEXLMECC问答[7月16日更新到第7部分]
作者:
readyu
时间:
2012-06-25,19:
00:
18
链接:
说明:
我曾经写过ECCTool用于学习和研究椭圆曲线加密在软件上的应用。
椭圆曲线密码学工具 ECCTooL v1.04
原帖年代久远不再更新。
v1.05版本我放在本帖3#。
FLexLM ECC是椭圆曲线签名的一个典型应用,不可不察。
我整理了一下FLEXLM ECC方面的研究心得, 准备把它完全写出来。
后面会有算法描述的例子代码。
FLEXLM ECC问答
(1)
readyu 2012.6
1. FLEXLM是个虾米东西?
FLEXlm是应用广泛的License管理工具。
宣称数千家EDA工具采用它管理授权。
FLEXlm对厂商来说,它的优点是证书管理功能强大, 支持平台众多。
对最终用户来说,它的缺点是不够友好, 比如Windows下,经常由于某些原因,flexlm服务启动错误。
对于破解者来说,它有着为数众多的教本。
维基百科上的条目为:
http:
//en.wikipedia.org/wiki/FLEXlm
FLEXLM本来属于GLOBEtrotter。
Macrovision曾经收购GLOBEtrotter。
2006年的时候,FLEXLM原来的开发组跑路,另起灶头,产品叫RLM。
2008年Macrovision把FLEXLM卖了。
现在叫FlexNet Publisher。
2. FLexLM 的ECC(椭圆曲线加密)怎么来的?
早期的flexlm采用的常规加密,不安全,能被做出lic。
这样的教程是很多的。
flexlm的安全性完全得不到保障,所以,自 v8(大约2001-2002)版本引入了公钥加密算法:
椭圆曲线加密。
从此,它一直是flexlm的金钟罩。
包括v9(2003-) , v10(2004-) , v11(2007-), 到最新的版本 v11.10 (2012) 。
FlexLm的ECC没有它自己的东西,完全采购自椭圆曲线加密系统的专利拥有者:
Certicom公司。
换而言之, flexlm ecc是购买自certicom的一套代码,相当于在腐朽的木门上套一层黄金甲。
OK, 从此它是不破金身了。
3. Certicom公司是何方神圣?
RSA和ECC是两大主流的公钥密码算法体系。
相比RSA,ECC晚出生10多年,推广不如前者。
Certicom公司是ECC的主要商业支持者,它拥有多项专利。
其地位可与RSA公司匹敌(RSA于2006年被EMC公司收购)。
有一则消息说,2003年美国国家安全局(NSA)以2500万美元支付了Certicom的26项技术许可。
另外有一则消息, Certicom 2007年起诉索尼公司,要求其支付PS3,DVD播放器等涉及加密技术侵权的专利费用。
Certicom的创办人Scott Vanstone,是加拿大滑铁卢大学的数学系教授和皇家科学院院士。
以前是研究椭圆曲线加密的,后来创办Certicom公司,努力把ECC从数学界推广到工业界。
Scott写过一本《椭圆曲线密码学导论》, 颇有名气。
4. FLEXLM 如何用的ECC?
说来话长。
一句话说:
FLexLM 在license验证上,主要用的ECDSA(椭圆曲线数字签名算法)。
具体的讲:
flexlm针对ECDSA有一些自己定义的东西以抵抗破解。
后面我会说到,这些自定义的
东西也不是那么牢固。
5. FLEXLM ECC的通用破解方法?
FLEXLM ECC的通用破解方法就是:
完全按照它的ECDSA算法签名, 只替换公钥和checksum, 写一个keygen生成license。
从逻辑上讲,生成license的方法和原厂的完全一致。
具体该怎么做呢:
首先, 实现标准的ECDSA签名算法。
椭圆曲线的具体算法,可以用现成的miracl,cryptopp等加密库代码。
只需要搞清楚ECDSA的使用方法就可以。
从早期版本 v9.2 (2004) , 到最新版本v11.10 (2012) 。
它的ecc公钥都是有checksum的。
替换公钥,首先得搞清楚checksum。
它只有一个函数,不算复杂,后面我会给出代码。
计算这个checksum, 对所有版本都是适合的。
其次, 公钥在文件里是加密打散的,有大量垃圾代码。
这些干扰使得flexlm可读性很差。
获取公钥需要调试。
在我写SlickEdit的patch keygen,我曾经采用调试的方法,非常不方便。
那么,有没有更方便的方法获取公钥呢?
ECC验证代码在它执行过程中有其自身的特点。
正如游戏辅助工具可以搜索血量,我们也可以写一个辅助工具从内存中获取公钥。
在很多次研究之后,我找出一个通用的方法。
不需要再拘泥于具体的代码,可以dump出公钥 ,然后用ecctool生成自己的公私钥对,替换公钥,然后可以就写keygen。
由此写了一个工具,对windows平台可直接操作。
对其它平台,把内存镜像出来操作即可。
对于非Windows平台,可以在VMware里面操作,制作一份snapshot,得到内存镜像。
算法上经过多次优化和排除错误数据,从2GB的内存镜像里找出正确的公钥,平均只需要6秒钟。
我对它的性能非常满意了。
总算是磨刀不误砍柴工。
所以,对于纯粹采用flexlm ecc sign的license,是可以做出通用的patch_keygen的,
不需要去考虑它有没有反调试,也不用管具体的细节。
只要dump 公钥, 替换公钥和checksum, 写patch_keygen就可以了。
6. 研究flexlm主要需要哪些资料?
flexlm相对来说资源丰富,基本上每个版本的sdk都有泄漏。
如果想深入研究flexlm的加密算法,flexlm sdk是必需的。
写kg是必须要读sdk的,值得注意的是v9.2 sdk sourcecode泄漏。
这个网上可搜索到。
sdk有一部分是c代码,里面最有用的是l_prikey.c, 这里有ECDSA验证的函数。
这个文件的尾部有300行comments,其中有一封email很值得一读。
ECC核心库没有源文件,只有lib文件。
在certicom目录下的lib里面,主要为libsb.lib等(Certicom 的加密库:
Security Builder)。
lib是混淆过了的,但是不影响ida反编译,只是不便于做sig文件。
主要依靠人脑识别函数,需要经验和时间。
7. flexlm的key加密强度有哪些?
以flexlm sdk v9为例,用宏定义表示LM_SIGN_LEVEL。
#define LM_SIGN2 2 /* SIGN2= */
#define LM_SIGN 1 /* SIGN= the default */
#define LM_NO_SIGN 0 /* license key */
v9以后,默认就采用ECC PUBKEY加密。
SIGN支持ECC,所以大部分情况下用SIGN比较多,有些用SIGN2。
LM_NO_SIGN 是传统的license key, 强度最弱,不建议使用。
ECC PUBKEY 只有3种类别, 113, 163, 239 bits。
对应的sign长度(字符数) , 字节为( bits + 7 )/8 字节数 , 打印出来,
用hex digits表示,ECC的SIGN长度分别是一对 30,42,60 [0-9,A-F]。
采用ECC的,pubkey_strength 必须定义为下面的一个类别,否则l_pubkey_verify会出错:
LM_STRENGTH_113BIT,LM_STRENGTH_163BIT,LM_STRENGTH_239BIT。
#define LM_STRENGTH_LICENSE_KEY 0
#define LM_STRENGTH_DEFAULT 1
#define LM_STRENGTH_113BIT 2
#define LM_STRENGTH_163BIT 3
#define LM_STRENGTH_239BIT 4
#define LM_STRENGTH_PUBKEY LM_STRENGTH_113BIT
#define LM_STRENGTH_VERYHIGH LM_STRENGTH_239BIT
在l_pubkey_verify 有这么一段初始化代码, 判断pubkey_strength。
代码:
switch(pubkey_strength)
{
case LM_STRENGTH_LICENSE_KEY:
return 0;
case LM_STRENGTH_113BIT:
ellipticCurve = &LM_PUBKEY_CURVE113BIT;
break;
case LM_STRENGTH_163BIT:
ellipticCurve = &LM_PUBKEY_CURVE163BIT;
break;
case LM_STRENGTH_239BIT:
ellipticCurve = &LM_PUBKEY_CURVE239BIT;
break;
default:
{
fprintf(stderr,
"LM_STRENGTH in lm_code.h has invalid value %d\n",
pubkey_strength);
fprintf(stderr,
"Use only LM_STRENGTH_[113|163|239]BIT, LM_STRENGTH_DEFAULT, OR LM_STRENGTH_LICENSE_KEY, exiting\n");
exit
(1);
}
}
下面,演示 113, 163, 239 bits的ECDSA签名一段最简单的文本,
msg:
"123"
sha hash:
40BD001563085FC35165329EA1FF5C5ECBDBBEEF
#define LM_SEED1 0x47d381a0
#define LM_SEED2 0x4fadf97c
#define LM_SEED3 0xc4ae244c
l_genkeys:
seed[3]=A081D3477CF9AD4F4C24AEC4
LM_PUBKEY_CURVE113BIT
prvlen=15, prv=00CFDF0247BF6EC0C8D1AA16DD505F
publen=16, pub=0301523DD4646BB65FE4238B8AB44D01
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
siglen=30
sig.r=0048D5DD2A57B1A1B357E98C193E63
sig.s=000A6FFDF76899F05ABFD2EDD9E065
LM_PUBKEY_CURVE163BIT
prvlen=21, prv=03DC603CB1683D43FF5631BBEEC5396D7BD4067300
publen=22, pub=0300368FE93082E1ACDD35222AD76782DBA8237B66EC
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
siglen=42
sig.r=039283F2FEA664BE7628F89BBA9D014E89E3868D2C
sig.s=017DA34A68C3FC64CB6EBE2B13676B04BE97EB5C20
LM_PUBKEY_CURVE239BIT
prvlen=30, prv=13C0E251A5130072A8D2D953EB2C94FAD487C0141B3197863BCC115D7B7E
publen=31, pub=035875A53B693A2861837E08FC6A7C58529DF52B565111C3DF55F18E34C9FA
>> l_prikey_sign_dbg start >>
signing "123"
hash=40BD001563085FC35165329EA1FF5C5ECBDBBEEF
>> l_prikey_sign_dbg done >>
inputlen=3, input=123
siglen=60
sig.r=1589FCFE91F988D28F7072DBF129424F0D71FA5E7AAC39258F3C408A656A
sig.s=0B50642E8ED77FC6A1E6F805CFA0299F44BC7B8035FE17142812B79EA576
sig.r sig.s组成一个完整的SIGN, 输出lic的时候,为了可读性, 一般切分为16 bit的分组(4个hex char)。
比如:
sig.r=038B9BE995B887B2665C02940C00155DD557C278AC95EADC1BD668DF185B
sig.s=1C50F25E81044E4DD9AD072699AAB4A63F4C99249AC8C091F476A6C73682
转化为:
SIGN=“ 038B9BE995B887B2665C02940C00155DD557C278AC95EADC1BD668DF185B
1C50F25E81044E4DD9AD072699AAB4A63F4C99249AC8C091F476A6C73682”
或者:
SIGN="038B 9BE9 95B8 87B2 665C 0294 0C00 155D D557 C278 AC95 EADC 1BD6 68DF 185B 1C50 F25E 8104 4E4D D9AD 0726 99AA B4A6 3F4C 9924 9AC8 C091 F476 A6C7 3682"
对flexlm的程序来说,是没有差别的。
都能处理。
8. flexlm用到的椭圆曲线有哪些?
flexlm用到三条椭圆曲线,都是有来历的, 名字分别为sect113r1, sect163k1, sect239k1。
具体参数可以参看:
http:
//en.wikipedia.org/wiki/SECG
SEC 2:
Recommended Elliptic Curve Domain Parameters (Version 2.0)
在flexlm lib里面, 它是写死的静态变量。
位置在
certicom\libcrvs.lib
保存为3个结构体:
struct ellipticCurveParameters sect113r1
struct ellipticCurveParameters ec163a02
struct ellipticCurveParameters ec239a03
头文件在
erticom\i86_n3\include\curves.h
代码:
/*=== Curves Definitions ==================
*
* sect113r1 (K-163 NIST), ec163a02 (SEC2, sect163k1) , ec239a03 (sec2, sect239k1)
*/
#define LM_PUBKEY_CURVE113BIT sect113r1
#define LM_PUBKEY_CURVE163BIT ec163a02
#define LM_PUBKEY_CURVE239BIT ec239a03
#define MAXIM_OID_CHARS 31
struct ellipticCurveParameters {
#pragma pack(4)
unsigned char oid[ MAXIM_OID_CHARS + 1 ];
struct {
unsigned char major[ 1 ];
unsigned char minor[ 1 ];
} version;
unsigned char checksum[ 4 ];
unsigned char fieldSize[ 2 ]; /* bits */
unsigned char fieldSizeOctets[ 1 ]; /* octets */
unsigned char basisType[ 1 ];
unsigned char modulus[ 32 ];
const unsigned char *ident1;
const unsigned char *ident2;
struct {
unsigned char a[ 32 ];
unsigned char b[ 32 ];
} curveParameter;
struct {
unsigned char value[ 64 ];
} generatingPoint;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} pointOrder;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} cofactor;
struct {
unsigned char size[ 2 ]; /* bits */
unsigned char value[ 32 ];
} curveOrder;
#pragma pack
(2)
struct {
unsigned char A[ 32 ];
unsigned char B[ 32 ];
} reserved;
} ;
9. flexlm ecc ellipticCurveParameters 结构体中 checksum的怎么计算的?
ellipticCurveParameters 带有4字节checksum,
每次初始化ECC计算时,都会校验checksum。
一方面为了避错, 另一方面为了反对篡改。
修改其中的公钥,必须重新计算checksum。
从libsb.lib里面分析反汇编代码, 逆向为c代码,经测试无误的代码:
代码:
int checksum(unsigned int len, void *src , int *val)
{
unsigned int i;
unsigned int h;
unsigned int c;
unsigned char *p = (unsigned char *)src;
if((p == 0) || (val == 0) || (len == 0))
return 1;
i = 0;
c = *val;
while(i < len)
{
c = p[i] + c * 16;
h = c & 0xF0000000;
if ( h !
= 0)
c ^= (h >> 24);
c &= ~h;
i++;
}
*val = c;
return 0;
}
unsigned int getbits(unsigned char *p, unsigned int len)
{
unsigned int val;
val = 0;
while(len --) {
val <<= 8;
val += *p++;
}
return val ;
}
unsigned int getbytes(unsigned char *p, unsigned int len)
{
unsigned int bits = getbits(p , len);
return ((bits + 7) >> 3);
}
int do_ecp_checksum(struct ellipticCurveParameters *e, int *sum1, int *sum2)
{
unsigned int val = getbytes(e->fieldSize, 2);
unsigned int bytes = val;
unsigned char *p = (unsigned char *)e;
#if 1
checksum(sizeof(e->oid), &e->oid, sum2);
checksum(sizeof(e->version.major), &e->version.major, sum2);
checksum(sizeof(e->version.minor), &e->version.minor, sum2);
checksum(sizeof(e->fieldSize), &e->fieldSize, sum2);
checksum(sizeof(e->fieldSizeOctets), &e->fieldSizeOctets, sum2);
checksum(sizeof(e->basisType), &e->basisType, sum2);
#endif
checksum(32u, p, sum1);
checksum(1u, p + 32, sum1);
checksum(1u, p + 33, sum1);
checksum(2u, p + 38, sum1);
checksum(1u, p + 40, sum1);
checksum(1u, p + 41, s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 椭圆曲线加密分析FLEXLM ECC问答 椭圆 曲线 加密 分析 FLEXLM ECC 问答