【翻译】prikey.c关于ecc内容翻译

“翻译by nujia”  这篇翻译来自prikey.c的最后部分。
*-------------------------------------------------------------

v7.1 改进

概述

v7.1有显著的改进,有很多新的特征但是没有公开文档,包括:

     
  o SIGN=, SIGN2= ... SIGNn=
  o v7.1 SIGN 如果是 non-CRO 格式, 会有12个字符, 但是也和以前的格式有点不同.
  o CRO 格式有三种sign长度。
  o 可以使用2段过滤器,以后可能不再支持。
  o 总的来说有6点关键的功能(5个是新增的)
    
    - license-key
    - 没有使用CRO的SIGN, 与license-key有些相似
    - 支持113位sign长度  (57字节)
    - 支持163位sign长度  (84字节)
    - 支持239位sign长度  (120字节)
    - 2段过滤器    (现在没有相关文档)

    2段过滤器以后不在支持。     

有很多灵活的功能如下:

          每个checkout可以定义/忽略通过LM_STRENGTH
          
          同样,每个FEATURE 可以定义根据lmcrypt里的LM_STRENGTH的值来确定sing的长度

          这样一个公司可以自己决定在应用程序中使用LM_STRENGTH的长度。
          
          不同sign长度的原因是软件公司可以用不同的seed或不同的key过滤器(比如两段过滤器)
          
下面主要讨论cro,最后再讨论non-cro

没有公开的文档是什么?为什么没有公开?
_____________________________
 
1. sign<n>目前没有公开文档,但是我认为这是非常重要的方法,将来会有很多公司采用它。

2. 在每个feature中使用不同的sign长度,目前没有公开,假如没有这个市场需求的话,我们以后将不再使用这项技术。

3. key-filters看起来已经过时了,目前还存在主要有以下几个原因:首先是它是我们采用cro的一个初始化方法。其次是我们认为仍有公司想利用这个技术来增加软件的安全性,

毕竟这不需要额外付费。最后一个原因也是最重要的一个原因是一些公司想不增加公钥的长度而获得更好的安全性。(译者注:这是不可能的,呵呵)



创建
-----
在创建一些key过滤器时,需要一步步详细的介绍。

第一个依赖关系序列如下:

    $DAEMON依赖于lsvendor.o
    lsvendor.o依赖于lm_new.o(lm_new.c)
    lm_new.c由lmnewgen生成
    lmnewgen依赖于lmcode.o(lmcode.c)
    lmcode.o由lmrand1生成,
    lmrand1依赖于lm_code.h
    
    (译者注:DAEMON->lsvendor.o -> lm_new.o ->lmnewgen ->lmcode.o ->lmrand1 ->lm_code.h)
    
这些依赖关系和flexlm v6.1是相同的,唯一不同的是lm_new.o里包含了更多的信息。 本质上,lm_code.h文件是用一个“模糊”的格式转换成了lm_new.o 。

下面是lc_new_job()里VENDORCODE结构的新添加的4项内容。

   int pubkeysize[LM_PUBKEYS];
  unsigned char pubkey[LM_PUBKEYS][LM_MAXPUBKEYSIZ];
        int strength;
  int (*pubkey_fptr)();     

LM_PUBKEYS 是 3, 所以如果使用CRO, 关于CRO的不同的信息就在VENDORCODE结构里。
pubkeysize,pubkey和长度都是计算公钥的必须的参数。

pubkey_fptr 存在于函数 l_pubkey_verify()中,除了license-generator,它叫l_prikey_sign()函数。

(这种格式用在任何license-key过滤器重,比如flexlm v6里的两段过滤器。这过滤器仍然有效,并且在servtest函数里测试过,但是我们不对此提供支持)

lm_new.o 现在包含了所有客户端的公钥信息。

公钥/私钥对


但是lm_code.h只包含SEED和VENDORCODE,它是怎样转变成公钥/私钥的呢?

公钥对由lmnewgen产生,seed3和seed4用来产生公钥对,如果seed3和seed4不变,那么每次运行都会产生相同的公钥对,但是如果你改变了seed的一位,公钥对的一半将会改变,

也就是这种改变的对应关系是不可能逆向的。从理论上讲,从公钥对是不能逆向获得seed3和seed4的。

所以,我们没有存储公钥对,ISV(独立软件开发商)应该注意到这一点。他们唯一要做的是保存好seed3和seed4。另外,一个license-generator比如像gtlicense理论上能获得

seed,为了生成license。


必须注意加密的seed3和seed4没有出现在发布的产品中,只有公钥出现在前台/后台程序中,而私钥仅仅出现在license-generator中。

lmcode.o包含了lm_code.h的信息,(lmcode.o由lmrand1程序产生。)

lmcode.o和lmnewgen.o链接生成lmnewgen程序,而它产生lm_new.c。 它调用l_gen_pkey_headers() 生成lm_new.o (它包含公钥 public-key) 和 lmprikey.h (它包含私钥 

private key)。
l_gen_pkey_headers() 最后调用 Certicom 的程序 sb_genKeyPair() 生成公钥/私钥对( public-key pairs)。

总结:lmnewgen用seed3和seed4制作公钥/私钥对。公钥在lm_new.c被“模糊”化。而私钥保存在lmprikey.h中,而lmprikey.h包含在license-generator源代码中。

LICENSE GENERATOR(license生成器)
_________________


包含了lmprikey.h,同时用LM_CODE_GEN_INIT 初始化 VENDORCODE结构。一旦初始化完毕,它与客户端唯一不同的两个地方是pubkey信息是私钥及pubkey_fptr的返回函数是
l_prikey_sign()。

当生成license时,sign的长度是必须的,它由CONFIG结构的L_CONF_STRENGTH_OVERRIDE确定。(警告:出于安全的考虑,L_CONF_STRENGTH_OVERRIDE在l_privat.h进行了宏定义。



license-generator有很多选择:你可以使用license-key,和/或其他长度的sign,但是你必须二者择其一。客户端指出使用哪种方法,并且确切的。


客户端/守护进程
______________

理论上讲,一个job可以有不止一个的LM_STRENGTH,而且不同的checkout可以有不同的LM_STRENGTH。我相信它能实现,但是我们的文档不会提及它,并且也不提供技术支持。我这

么说仅仅是表明这个方法是可行的。

lc_new_job调用l_init()函数,在这个函数里,VENDORCODE结构的pubkey传递给函数l_add_key_filter()。它将L_KEY_FILTER 赋值给job->key_filters,这样也可以提供key过滤

器的作用。当然不同的sign长度也会有不同的L_KEY_FILTER。

客户端(CLIENT)


客户端不用考虑以下两个可能:

           1) 需要多长的strength
                  LM_A_STRENGTH_OVERRIDE 由job->L_STRENGTH_OVERRIDE 确定

           2)需要sign的长度 
                 LM_A_SIGN_LEVEL 由 job->L_SIGN_LEVEL 确定

缺省的strength在lm_code.h里设置,而且等于VENDORCODE结构的strength。缺省的key-level是1,当L_SIGN_LEVEL为0时,意味着使用12位的license-key,而不使用SIGN。

VDAEMON


守护进程(后台程序)daemon用来验证license文件中所有的license-key/signatures是否正确。如果有额外的验证也能完成。为了验证license的正确与否,它需要所有的3个CRO 

strength,即时使用license-key而没有使用CRO sign。

参见:
testsuite/st_vers.c: test 49.
testsuite测试所有的feature,也可能执行验证这些feature是如何工作的。

utils/lmnewgen.c:
它生成公钥,主要是生成lm_new.c,其中lm_new.c包含模糊化的公钥。



To: danielbirns@hotmail.com, slangford@certicom.com, bolson@certicom.com, David Znidarsic <davidz@globes.com>, Matt Christiano <matt@globes.com>
Subject: Summary of review
Cc: richard Mirabella <rich@globes.com> 

发现了ECC的一个安全漏洞


  o 在handshake中使用seed3和seed4,我们可以用一台运行较快的PC用大约一天的时间暴力破解出seed3和seed4。
  o 假如在signature生成过程不超过1毫秒,那么第一个一半如果signature为2个signature(这句话不会翻译,:()。假如是真的,有经验的hacker就能立刻获得私钥。这

对于113位的sign(57字节)将很快找到私钥,我的PC的运算速度就可以。


建立(setup)       

  o 96位的seed S。
  o 提供优化的选项给ISV(独立软件开发商) 生成可靠的随机96位seed,或者客户自己定义96位的seed n。
  o 从96位的seed S和n生成更多的96位的seed Tn,使用FIPS186随机数发生器产生这些96 位的seed Tn。
  o 这些Tn必须一次生成。
  o 新的客户使用T2和T3生成seed1~seed4,所以他们只需要96位的seed S。(LM_SEED1-3共12字节96位)
  

公钥/私钥对的产生

  o 用T1生成公钥和私钥
  o 用T1和常数113生成一个113位的公钥/私钥对
  o 同样用T1和常数163及239生成相应长度的公钥/私钥对
  o 确保这些公钥/私钥对不是相同的,即使seed只相差1也足够了。
  
  
signing

  o 使算法暂时停止工作
  o Private key,消息的散列。
  o 相同的feature会产生相同signature 
  o 为每个signature需要一个不同的Certicom "context"。(Certicom 公司就是提供ECC软件服务的公司。)
  

测试

  o 加一个测试去避免发生上面提到第二种情况----113位有第一个signature的一半相同。
  o 标记f1-f100并且查找前半部分相同的signature
  
ISV(独立软件开发商)用如下方法加强保护

  o Brian Olson 提到的方法对于私钥和seed3-4在客户端是安全的。目前的技术水平硬件狗的是合适的。除了seed和实际的signing取代了硬件狗。一般认为这是安全的和

方便的。当然现在硬件狗没有广泛使用,主要没有被更多的客户接受。
  o 我的观点是没有真正的安全,在ISV(独立软件开发商)实践过程中,不愿意使用,或者是找到其他方法绕过这种复杂的验证。举个例子,假设每次生成license你都被要求输入password。

这个password有96位,或者是相同长度英语短语,这将给hacker可乘之机。这两个方法都太长而难以操作,因为你每次要用的时候都需要输入。于是,password就存在硬盘上的某

个文件里,或者登陆一次后永不注销,这些都是极不安全的做法。
  o 也就是说我们现在需要做一项工作:改进文档,解释什么需要保护。如今,大容量的硬盘上有太多的文件,这些文件没有注释,其中也包括S或者私钥。
  

结论

  o 我认为hacker唯一可以破解的地方是通过handshake来获得seed3和seed4,除非hacker发现其它的漏洞。
  o 还有两步需要做
         1)Macrovision高级工程师应该查看源代码试图找到其他的漏洞。这样就能在hacker发现之前修补漏洞。
         2)所有的Certicom 代码都是c语言写的。我可以发送最终版本给Certicom 公司,让他们发现其中明显的错误用法。