SSL使用USBKey证书的需求分析(转)

12 篇文章 1 订阅
2 篇文章 0 订阅

背景

很多系统,如炒股软件采用客户端/服务器结构,用户安装客户端炒股软件在本地计算机,并与证券公司的服务器系统连接,以完成股票的买卖等操作。

客户端与服务器端采用SSL安全通道连接,以防止第三方窃听和篡改通信的内容。但连接时不使用双向认证或者只使用文件证书来进行双向认证。这样做会存在一些风险。

1、 任何人获取了本地主机的访问权限就可以连接到服务器端。

2、 文件证书保存在本地计算机的磁盘上,任何人获取了本地计算机的访问权限就可对其修改、替换或者删除.

所以,要使用USBKey证书来替换文件证书来解决文件证书的安全风险。另外,有的软件公司提出了一个USBKey证书和文件证书两者兼顾的想法,既当客户端检查到有USBKey插入,并能够读出用户的证书时,则使用USBKey来实现服务器端认证客户端,并不需要用户输入PIN码,并当有多个USBKey插入时,也不需要用户选择。

如未检查到USBKey插入,则还使用原来的文件证书.  另外,需求不需要USBKey支持对称密码算法,只需要支持客户端认证算法。思考他们的需求,他们可能是出于以下的考虑。

1、 他们可能是对OpenSSL客户端认证如何使用USBKey证书不太了解,并基于文件证书的认证是他们已经存在的应用模式.

2、 他们不需要USBKey支持对称的密码算法,可能是基于股票交易的实时性需求方面的考虑.

解决方案

USBKeyOpenSSL客户端中的使用有两个方面的应用,第一是实现客户端认证,第二是实现对称算法的加密和解密。以上的需求,只要满足客户端认证的需求就可以了。

OpenSSL实现客户端认证的方法有两种。在OpenSSL0.9.8i以下的版本中,客户端认证是通过回调函数的方法来实现的。在OpenSSL0.9.8i以上的版本中,客户端认证是通过引擎来实现的,并兼容回调函数的方法,既当设置了客户端认证所要使用的引擎,则使用引擎。未设置引擎,而设置了回调函数,则使用回调函数的方法。

实现客户端认证我们可提供三种方案。

回调函数的方法。

l 在SSL_CTX结构中定义了成员int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);的回调函数,用户获取客户端证书及相关联的密钥,此函数返回1,指明函数调用成功,返回其它值,表示获取客户端证书及密钥失败。获取的密钥被包装在EVP_PKEY结构中,之后, EVP_SignFinal函数将调用这个密钥来执行签名的操作.

l 我们可提供给用户一个动态库,中实现一个此回调函数的定义的导出函数,这个导出函数中实现从USBKey中取回用户的证书及相关联的密钥(公钥和私钥)的功能

l 以RSA算法为例,动态库生成一个RSA结构及RSA算法的实现,以提供给EVP_SignFinal函数来调用它,具体的实现如下。

i. RSA结构中的const RSA_METHOD *meth 成员变量需设置为USBKey操作RSA密钥的相关算法实现的函数,并必须实现 int (*rsa_sign)(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 函数。

ii. 变量meth中的成员flags ,必须设置为RSA_FLAG_SIGN_VER。

iii. RSA结构中的CRYPTO_EX_DATA ex_data成员,将用来保存与私钥相关联的信息。(PKCS11的私钥对象的句柄,及访问此私钥的密码等)

iv. RSA的结构中的BIGNUM *n成员,保存公钥的模

v. RSA的结构中的BIGNUM *e成员,保存公钥的指数

l 这个成员变量可通过SSL_CTX_set_client_cert_cb函数来设置.

基于CSP的引擎的方法

l 在OpenSSL0.9.8i以上版本的源码中,实现了基于windows crypt api的调用的引擎,它满足客户端认证的需求,需实现了以下的控制功能

vi. 设置所用的CSP的名称

vii. 设置所用的证书store的名称,默认是’MY’

l 在Openssl0.9.8i以上的版本的引擎的数据结构中,存在成员ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert,它指明并需实现获取客户端证书及相关密钥的函数的指针。

viii. 定义为typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,  STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,  STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); 

ix. 主要的参数指明如何在本地的证书库如何过滤证书的操作。

1. ca_dn ,指明了所需的客户端证书的颁发者

2. pcert  , 指明所要输出的客户端证书

3. pkey, 指明所要输出的客户端证书相关联的密钥

4. ui_method ,指明需弹出用户的界面来选择证书的方法

l 以RSA算法为例,引擎要生成一个RSA结构及RSA算法的实现,以提供给EVP_SignFinal函数来调用它,具体的实现如下。

x. RSA结构中的const RSA_METHOD *meth 成员变量需设置为USBKey操作RSA密钥的相关算法实现的函数,并必须实现 int (*rsa_sign)(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 函数。

xi. 变量meth中的成员flags ,必须设置为RSA_FLAG_SIGN_VER。

xii. RSA结构中的CRYPTO_EX_DATA ex_data成员,将用来保存与私钥相关联的信息。(PKCS11的私钥对象的句柄,及访问此私钥的密码等)

xiii. RSA的结构中的BIGNUM *n成员,保存公钥的模

xiv. RSA的结构中的BIGNUM *e成员,保存公钥的指数

l 需设置openssl0.9.8i以上版本中的SSL_CTX结构中的成员变量client_cert_engine为引擎的实例,可使用SSL_CTX_set_client_cert_engine函数来设置

基于PKCS11的引擎的方法

l 在OpenSSL0.9.8i以上版本的源码中,实现基于PKCS11的调用的引擎,它满足客户端认证的需求,需实现了以下的控制功能

xv. 设置PKCS11DLL的路径

xvi. 设置访问私钥对象的用户PIN

xvii. 设置所访问的USBKey的对应的slot

l 在Openssl0.9.8i以上的版本的引擎的数据结构中,存在成员ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert,它指明并需实现获取客户端证书及相关密钥的函数的指针。

xviii. 定义为typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,  STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,  STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); 

xix. 主要的参数指明如何在本地的证书库如何过滤证书的操作。

1. ca_dn ,指明了所需的客户端证书的颁发者

2. pcert  , 指明所要输出的客户端证书

3. pkey, 指明所要输出的客户端证书相关联的密钥

4. ui_method ,指明需弹出用户的界面来选择证书的方法

l 以RSA算法为例,引擎要生成一个RSA结构及RSA算法的实现,以提供给EVP_SignFinal函数来调用它,具体的实现如下。

xx. RSA结构中的const RSA_METHOD *meth 成员变量需设置为USBKey操作RSA密钥的相关算法实现的函数,并必须实现 int (*rsa_sign)(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa); 函数。

xxi. 变量meth中的成员flags ,必须设置为RSA_FLAG_SIGN_VER。

xxii. RSA结构中的CRYPTO_EX_DATA ex_data成员,将用来保存与私钥相关联的信息。(PKCS11的私钥对象的句柄,及访问此私钥的密码等)

xxiii. RSA的结构中的BIGNUM *n成员,保存公钥的模

xxiv. RSA的结构中的BIGNUM *e成员,保存公钥的指数

l 需设置openssl0.9.8i以上版本中的SSL_CTX结构中的成员变量client_cert_engine为引擎的实例,可使用SSL_CTX_set_client_cert_engine函数来设置

OpenSSL如何使用引擎

OpenSSL中,存在一个被命名为 'dynamic’  的引擎,OpenSSL编译时,会自动的被编译到lib中,它的功能就是动态的加载一个SSL应用所需要的引擎。这样的引擎往往被称为动态引擎。

动态引擎往往是一个DLL文件或者一个SO文件,他必须有两个导出的函数,一个函数名是v_check,执行版本检查的功能。一个函数名bind_engine,支持使应用程序能够调用此引擎的功能函数。

当加载一个动态引擎时,需要使用 'dynamic’ 的引擎的如下的控制流程。

1、 ENGINE_ctrl_cmd_string(e, "SO_PATH", “dll的路径”, 0);

n 设置DLL文件或者SO文件的路径

2、 ENGINE_ctrl_cmd_string(e, "ID", “动态引擎的描述串”, 0);

n 设置动态引擎的描述符串

3、 ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);

n 加载此动态引擎

三种方法的不同的特点

1. 回调函数的方法只能够实现获取客户端证书及相关联的密钥,从而实现客户端认证的需求,并不能够支持OpenSSL所需的对称密码算法的功能需求。另外,这种方法可适应多种平台,使用起来比较灵活,也可根据用户的需求增加额外的功能。

2. 使用CSP引擎的方法将仅限于windows平台,在OpenSSL0.9.8i以上的版本中可以直接使用它的客户端认证的功能,而不需要再开发。但是,如果用户需要SSL的对称算法的支持,则需要再开发。

3. 使用PKCS11引擎的方法可支持多种平台,可满足用户的客户端认证及对称密码算法加密与解密的功能需求,并可根据用户的需求增加额外的功能,但开发的工作量相对较大。

 

From:http://14521448.blog.hexun.com/53920443_d.html

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值