SlideShare a Scribd company logo
1 of 58
技术交流 - 二代支付信息安全及其代收付实现
                        李潜德
                      2012.7.30
              广州金电图腾软件有限公司
问题域

•   什么是电子信息安全
•   支付二代改进了什么
•   改进的理论支持是什么
•   该理论支持有何实现
•   如何学习该实现
•   该实现如何应用到代收付
电子信息安全

1.   确保电子信息在传输、存取和处理过程中,保持其保密性、完整性和可用性,并实现鉴别、授权
     、访问控制,抗否认性及可服务性等安全功能。
2.   基本内容:实体安全、运行安全、信息资产安全、人员安全
3.   保证措施:机构安全制度建设(其中密钥管理:生成、存储保护、备份恢复、分发装载、使用更换
     、销毁删除、归档终止);相关法律、法规、标准。
从支付接口看安全 - 支付一代
证明接收者能够核实发送者发送了这样的消息,而且只发送了一次。

全国押(还是地方?)密钥 -> 产生 MAC 。
加押字串包含流水号。

1.   完整    -   能够确保消息不被修改 -- OK
2.   鉴别    -   能够确认消息的发送者身份 -- NO
3.   防抵赖   -   能够防止消息发送者抵赖 -- NO
4.   防抵赖   -   能够保证消息不被重放 -- OK
从支付接口看安全 - 支付二代
数字签名。
加签字串包含流水号。



1.   完整    -   能够确保消息不被修改 -- OK
2.   鉴别    -   能够确认消息的发送者身份 -- OK
3.   防抵赖   -   能够防止消息发送者抵赖 -- OK
4.   防抵赖   -   能够保证消息不被重放 -- OK
公钥基础设施 (PKI)
公钥基础设施( PKI )

公钥基础设施是由公
开密钥密码技术、数
字证书、证书认证中
心和关于公开密钥的
安全策略等基本成分
共同组成,管理密钥
和证书的系统或平台
。
RSA :公开密钥密码
技术中的一种。
数字证书认证机构( CA,
      Certificate Authority )

负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的
合法性检验的责任。


CA 也拥有一个证书(内含公钥)和私钥。网上的公众用户通过验证 CA 的签字从而信任 CA ,任何人
都可以得到 CA 的证书(含公钥),用以验证它所签发的证书。
数字证书
证书实际是由证书签证机关( CA )签发的
对用户的公钥的认证。包含用户的信息,用
户的公钥,还有 CA 中心对该证书里面的信
息的签名。

常用证书文件后缀名
.cer,.crt,.der - 二进制的 DER 文件格式,不包
含私钥
.pem         - 对二进制的 DER 文件格式再用
Base64 编码后的文件,不包含私钥
.p7b,.p7c - PKCS#7 证书格式,仅包含证书
和 CRL 列表信息,不包含私钥
.pfx,p12      - KCS#12 文件 , 包含证书(公钥
)和私钥(受密码保护),以及完整的证书
链信息
证书链 (Certificate Chain)

证书链由两个环节组成—信任锚( CA 证书)环节和
已签名证书环节。自我签名的证书仅有一个环节的长
度—信任锚环节就是已签名证书本身。


证书链可以有任意环节的长度,所以在三节的链中,
信任锚证书 CA 环节可以对中间证书签名;中间证书
的所有者可以用自己的私钥对另一个证书签名。


可以遍历证书链以验证有效性,有效的证书链就构成
了信任链。
根证书
根证书是 CA 认证中心给自己颁发的证书 , 是信任
链的起始点。



安装根证书意味着对这个 CA 认证中心的信任,表
明您对该根证书以下所签发的证书都表示信任,而
技术上则是建立起一个验证证书信息的链条,证书
的验证追溯至根证书即为结束。
证书吊销列表
CRL 一定是被 CA 所签署的,可以使用与签发证书相同的私钥,也可以使用专门的 CRL 签发私钥。 CRL
中包含了被吊销证书的序列号。



证书具有一个指定的寿命,但 CA 可通过称为证书吊销的过程来缩短这一寿命。 CA 发布一个证书吊销
列表 (CRL) ,列出被认为不能再使用的证书的序列号。
PKI 实现之一 -OPENSSL
OpenSSL 简介 - 概览

• 功能丰富且自包含的开源安全工具箱
• 以 C 语言为开发语言
OpenSSL 简介 - 关注功能
•   非对称加解密算法
•   数字证书编解码
•   数字证书验证
•   PKCS7 标准实现
•   PKCS12 个人数字证书格式实现
OpenSSL 简介 - 学习方法

• Apps 包含工具源码
• Demos 包含范例源
  码
OpenSSL 应用 - 初始结束
• 初始化
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();

• 结束
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_state(0);
ERR_free_strings();
OpenSSL 应用 - 错误处理

• 打印当前错误
ERR_print_errors_fp (gf_log_ptr);
OpenSSL 应用 - 内存分配

• 可以记录内存的分配与释放
• 可以基于记录将内存泄露的情况打印出来
OpenSSL 应用 - 内存分配
•       打开内存跟踪记录
    CRYPTO_malloc_debug_init();
    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

•       申请内存
    gs_msg_buf = OPENSSL_malloc(MSG_MAX_LEN);

•       释放内存
    OPENSSL_free(gs_msg_buf);

•       打印内存泄露
    CRYPTO_mem_leaks_fp(arch_trc_get_trc_file());

[13:12:54] 3156 file=digest.c, line=305, thread=3764460, number=104, address=1102B9FB0
[13:11:07] 383 file=mbfe2_acore_app.c, line=222, thread=3764460, number=6291456, address=1102C4FB0
6291560 bytes leaked in 2 chunks
OpenSSL 应用 - 抽象 IO

• 对常见 IO 的抽象封装
• 可以组成管道
OpenSSL 应用 - 抽象 IO- 内存 IO

•     从内存中构建 IO
inData = BIO_new_mem_buf(s_x509_pem, strlen(s_x509_pem));

•     在其他函数中使用该 IO
x509 = PEM_read_bio_X509(inData, NULL, NULL, NULL);

•     释放该 IO
BIO_free_all(inData);
OpenSSL 应用 - 抽象 IO- 嵌套 IO

•     从内存中构建 IO
out = BIO_new(BIO_s_mem());

•     创建嵌套 IO
b64 = BIO_new(BIO_f_base64());
out = BIO_push(b64, out);

•     释放该 IO
BIO_free_all(out);
OpenSSL 应用 -PEM
• Privacy Enhanced Mail , OpenSSL 的默认信
  息存放方式
• 包含如下信息
  1) 内容类型
  2) 头信息
  3) 信息体
OpenSSL 应用 -PEM
•   CFCA 根证书
-----BEGIN CERTIFICATE-----^M
MIICvDCCAiWgAwIBAgIEPPx1qzANBgkqhkiG9w0BAQUFADAgMQswCQYDVQQGEwJD^M
TjERMA8GA1UEChMIQ0ZDQSBSQ0EwHhcNMDIwNjA0MDczOTIwWhcNMjIwNjA0MDgw^M
OTIwWjAgMQswCQYDVQQGEwJDTjERMA8GA1UEChMIQ0ZDQSBSQ0EwgZ8wDQYJKoZI^M
hvcNAQEBBQADgY0AMIGJAoGBALjj9EbWFRz6rj4a42KpSB+jPqoHnkjmr3S69P4A^M
icz9r6ZfFat1SvjJAG4XjB69ejGczrP2Acp3JVyH3jDMXSa4EfEfw/Erom1ILaWy^M
jKTl/Cs78oJMjGyiZT5CJ14gH6o9rVYMEr2FjH6a7SJKJ/P/YBiQzNh6h97gynIy^M
J5ChAgMBAAGjggEBMIH+MBEGCWCGSAGG+EIBAQQEAwIABzBCBgNVHR8EOzA5MDeg^M
NaAzpDEwLzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCENGQ0EgUkNBMQ0wCwYDVQQD^M
EwRDUkwxMCsGA1UdEAQkMCKADzIwMDIwNjA0MDczOTIwWoEPMjAyMjA2MDQwODA5^M
MjBaMAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBQAmjTyUflTFGF0bnKhBt7HgXAb^M
vDAdBgNVHQ4EFgQUAJo08lH5UxRhdG5yoQbex4FwG7wwDAYDVR0TBAUwAwEB/zAd^M
BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEA^M
Jv+gsBZv4egVVt7qPYUM8M0rfT2TjUd/vm7l7kmfGHLz2hJR2fMhgMXo8sxPBA6D^M
L3ZW08X+UA5Gsa34enwtkDEVTe1Nvpz6L+W1C9hWpzyKsK0HQbrC5xTLAcEl7nlt^M
Zb/JN44RbcevYcdAt3SyOAaoOtGljBQwFI0TFdMwHrg=^M
-----END CERTIFICATE-----^M
OpenSSL 应用 -PEM- 证书
•     读取证书
x509 = PEM_read_bio_X509(inData, NULL, NULL, NULL);

•     保存证书
err = PEM_write_bio_X509(bMem, x509);
OpenSSL 应用 - 证书
• 从证书获取公钥
pubkey=X509_get_pubkey(x509);

• 从证书获取颁发者
name = X509_get_issuer_name(signer);

• 释放证书结构
X509_free(g_x509);
OpenSSL 应用 - 证书仓库
• 用于简化证书链等操作
OpenSSL 应用 - 证书仓库
• 搭建证书仓库
g_X509_store = X509_STORE_new();
• 设置检查所有证书是否撤销
X509_STORE_set_flags(g_X509_store, X509_V_FLAG_CRL_CHECK);
• 设置证书链检查深度
X509_STORE_set_depth(g_X509_store, 10);
• 设置回调函数,在回调函数中检查是否忽略错误
X509_STORE_set_verify_cb_func(g_X509_store, _verify_callback);
OpenSSL 应用 - 证书仓库
• 指定证书搜索方法
lookup=X509_STORE_add_lookup(g_X509_store, X509_LOOKUP_hash_dir());
• 指定证书来源
sprintf(szCACertFileName, "%s/keystore/cacerts", g_home);
err = X509_LOOKUP_add_dir(lookup,szCACertFileName,X509_FILETYPE_PEM);
OpenSSL 应用 -PKCS12


• 一种交换数字证书的加
  密标准
• 用于描述个人身份信息
用户公钥、私钥、证书等
OpenSSL 应用 -PKCS12
• 读取 PKCS12 信息
p12 = d2i_PKCS12_fp(fp, NULL);
• 解析 PKCS12 信息
PKCS12_parse(p12, gf_PKCS12Password, &g_privkey, &g_x509, NULL)
• 释放 PKCS12 内部结构
PKCS12_free(p12);
OpenSSL 应用 -EVP

• 对编解码、摘要、加解密等提供统一函数
  入口
OpenSSL 应用 -EVP-Base64
• 定义并初始化编码上下文
EVP_ENCODE_CTX ectx;
EVP_EncodeInit(&ectx);

• 不断进行编码输出
EVP_EncodeUpdate(&ectx, t, &ebuflen, f, n);

• 结束编码
EVP_EncodeFinal(&ectx, t+ebuflen, &ebuflen);
OpenSSL 应用 -EVP-Base64
• 定义并初始化解码上下文
EVP_ENCODE_CTX ectx;
EVP_DecodeInit(&ectx);

• 不断进行解码输出
EVP_DecodeUpdate(&ectx, t, &ebuflen, f, n);

• 结束解码
EVP_DecodeFinal(&ectx, t+ebuflen, &ebuflen);
OpenSSL 应用 -EVP-Base64
• 直接编码
EVP_EncodeBlock(signB64,sign,signLen);

• 直接解码
len = EVP_DecodeBlock(sign, signB64, strlen(signB64));
OpenSSL 应用 -EVP-Base64
• 最大区别
 第一种每 64 位会自动加上换行符 (n) ,方便阅读。
第二种一长串输出。
OpenSSL 应用 -EVP-MD5
• 计算 MD5
err = EVP_Digest(pDetailBgn, pTmp - pDetailBgn, md, NULL, EVP_md5(), NULL);
OpenSSL 应用 -EVP- 裸签
• 裸签
EVP_MD_CTX md_ctx;
EVP_SignInit (&md_ctx, EVP_sha1());
EVP_SignUpdate (&md_ctx, pOrgData, nOrgDataSize);
signDataSize = *pSignDataSize;
err = EVP_SignFinal (&md_ctx, pSignData, &signDataSize, g_privkey);
EVP_MD_CTX_cleanup(&md_ctx);
OpenSSL 应用 -EVP- 裸验签
• 裸验签
EVP_MD_CTX md_ctx;
EVP_VerifyInit(&md_ctx, EVP_sha1());
EVP_VerifyUpdate(&md_ctx, pOrgData, nOrgDataSize);
err = EVP_VerifyFinal (&md_ctx, pSignData, nSignDataSize, pubkey);
EVP_MD_CTX_cleanup(&md_ctx);
OpenSSL 应用 -EVP- 其他
• 释放公私钥
EVP_PKEY_free(g_privkey);
OpenSSL 应用 -PKCS7


• 加密消息的语法标准,由 RSA 安全体系在公钥加密系统中
  交换数字证书产生的一种加密标准。
OpenSSL 应用 -PKCS7
• P7 分离式签名
p7 = PKCS7_sign(g_x509, g_privkey, NULL, in, PKCS7_DETACHED | PKCS7_NOATTR);
• 获取 P7 字串
err = i2d_PKCS7_bio(out,p7);
• 释放 P7 内部结构
PKCS7_free(p7);
OpenSSL 应用 -PKCS7
• 从 P7 字串得到 P7 内部结构
p7 = d2i_PKCS7_bio(inSign, NULL);
• 验证
err = PKCS7_verify(p7, NULL, g_X509_store, inData, NULL, 0);
• 释放 P7 内部结构
PKCS7_free(p7);
OpenSSL 工具 -CRL 格式转换

从 DER 格式转换到 PEM 格式
openssl crl -inform DER -in crl.crl -outform PEM -out crl.pem
OpenSSL 工具 - 证书格式转换

从 DER 格式转换到 PEM 格式
openssl x509 -inform DER -in der.cer -outform PEM -out pem.cer
代收付实现
代收付实现 - 登录 - 接口


序                                                                                              加签
    或   报文要素                   <XML Tag>      属性       类型                       备注
号                                                                                              要素

        Message root           <LoginReq>     [1..1]                            LoginRequest

        GroupHeader            <GrpHdr>       [1..1]   【业务头】                                   √

        LoginInformation       <LoginInf>     [1..1]


        --LoginOperationType
                               <LoginOprTp>   [1..1]   LoginOperationTypeCode   禁止中文           √
        操作类型
代收付实现 - 登录 - 接口
                                                                                    加签
序号   OR   要素名称                       XML Tag          属性       类型            备注
                                                                                    要素

          MessageIdentification
          报文标识号
                                     <MsgId>          [1..1]   Max35Text     禁止中文   √
          CreationDateTime
          报文发送时间
                                     <CreDtTm>        [1..1]   ISODateTime   禁止中文   √
          InstructingParty           <InstgPty>       [1..1]

          --InstructingDirectParty
          发起直接参与机构
                                     <InstgDrctPty>   [1..1]   Max14Text     禁止中文   √
          --InstructingParty
          发起参与机构
                                     <InstgPty>       [1..1]   Max14Text     禁止中文   √
          InstructedParty            <InstdPty>       [1..1]

          --InstructedDirectParty
          接收直接参与机构
                                     <InstdDrctPty>   [1..1]   Max14Text     禁止中文   √
          --InstructedParty
          接收参与机构
                                     <InstdPty>       [1..1]   Max14Text     禁止中文   √
          SystemCode
          系统编号
                                     <SysCd>          [1..1]   SystemCode    禁止中文   √
          Remark
                                     <Rmk>            [0..1]   Max256Text    允许中文
          备注
代收付实现 - 登录 - 配置加签报
              文
static MSGSIGNMAPPING msgSignMapping[] =
{
  ….
     /* 签到签退请求报文 */
     { "ccms.805.001.02", 1, NULL, xmlEntry_ccms_805},
     ….
};
代收付实现 - 登录 - 配置加签要
            素
/* 签到签退请求报文 */
static XML_PATH_ENTRY xmlEntry_ccms_805[] =
{
   {"/Document/LoginReq/GrpHdr/MsgId", "", ""},
   {"/Document/LoginReq/GrpHdr/CreDtTm", "", ""},
   {"/Document/LoginReq/GrpHdr/InstgPty/InstgDrctPty","", ""},
   {"/Document/LoginReq/GrpHdr/InstgPty/InstgPty","", ""},
   {"/Document/LoginReq/GrpHdr/InstdPty/InstdDrctPty","", ""},
   {"/Document/LoginReq/GrpHdr/InstdPty/InstdPty","", ""},
   {"/Document/LoginReq/GrpHdr/SysCd","", ""},
   {"/Document/LoginReq/LoginInf/LoginOprTp","", ""},
   {"","", ""}
};
代收付实现 - 登录 - 报文实例
{H:02906581000018 BEPS           BEPS20120425175450XMLccms.805.001.02 2012042
5MF100000001220120425MF10000000123U            }^M
{S:GHR4geKYh5mtnu9yEjrxpfX7inV7FyFHp0ErN2yI4bl/DJvn1udv/o2QeTpfh7+mLLhm2TQi5oX4AxjzdcqFhQE8uB1mfWSGgjJjcFOWbPXa10XLBxSuYMm/tFWdc38uJHBzFuX6wYogsaiXLmQV5bvkU5
18MEpQwZBTz5ZvjMU=}^M
<?xml version="1.0" encoding="UTF-8"?>^M
<Document xmlns="urn:cnaps:std:ccms:2010:tech:xsd:ccms.805.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">^M
    <LoginReq>^M
        <GrpHdr>^M
             <MsgId>2011110901000004</MsgId>^M
             <CreDtTm>2012-04-25T17:54:50</CreDtTm>^M
             <InstgPty>^M
                 <InstgDrctPty>906581000018</InstgDrctPty>^M
                 <InstgPty>906581000018</InstgPty>^M
             </InstgPty>^M
             <InstdPty>^M
                 <InstdDrctPty>NT00</InstdDrctPty>^M
                 <InstdPty>NT00</InstdPty>^M
             </InstdPty>^M
             <SysCd>BEPS</SysCd>^M
             <Rmk> 骞垮穅揲 ^ 佣琛 ^ 嚏 ^ 缘瀛 ^ 戌籢隅甞卒腑蹇 ^ 娩唬鎊远浠 ^ 劐癪祥葭錨劝绛鹃 ^ 繼 /Rmk>^M
        </GrpHdr>^M
        <LoginInf>^M
             <LoginOprTp>OT00</LoginOprTp>^M
        </LoginInf>^M
    </LoginReq>^M
</Document>^M
代收付实现 - 登录 - 报文加签串


[
代收付实现 - 裸签名
int RawSign(int nSocketFd, unsigned char* pOrgData, int nOrgDataSize, char* sCertDN, unsigned char* pSignData, int*
pSignDataSize)
{
  ….
  /* 用私钥对数据进行裸签 */
  EVP_SignInit (&md_ctx, EVP_sha1());
  EVP_SignUpdate (&md_ctx, pOrgData, nOrgDataSize);
  signDataSize = *pSignDataSize;
  err = EVP_SignFinal (&md_ctx, pSignData, &signDataSize, g_privkey);
  /* 释放资源,避免内存泄露 */
  EVP_MD_CTX_cleanup(&md_ctx);
  ….

    * pSignDataSize = signDataSize;
    return (0);
}
代收付实现 - 函数调用链
代收付实现 - 继续了解

可参考的独立程序

SecureDemo

SecureTool


SVN 路径: http://56.16.32.156:8001/svn/code/mbfe2/Source/Main/src/app/secure
参考资料
•   《 openssl 编程 .pdf 》 - 赵春平
•   mbfe2dev - 金电图腾
•   openssl-0.9.8u.tar.gz - www.openssl.org
•   公钥密码技术讲义 - 四川大学计算机网络与安全研究所
•   信息安全与加密解密核心技术 - 黄元飞
•   百度百科
•   维基百科
•   二代接口文档
谢谢

More Related Content

Similar to 技术交流 支付二代信息安全及其代收付实现

希望科技研发部变量命名及编码规范
希望科技研发部变量命名及编码规范希望科技研发部变量命名及编码规范
希望科技研发部变量命名及编码规范
Hongjian Wang
 
電腦網路 網路安全
電腦網路 網路安全電腦網路 網路安全
電腦網路 網路安全
bruce761207
 
Internet Security
Internet SecurityInternet Security
Internet Security
bruce761207
 
Brochure ahn lab trusguard utm
Brochure ahn lab trusguard utmBrochure ahn lab trusguard utm
Brochure ahn lab trusguard utm
ahnlabchina
 
網站設計100步
網站設計100步網站設計100步
網站設計100步
evercislide
 
Times Ten Training
Times Ten TrainingTimes Ten Training
Times Ten Training
Li Chen
 
浅谈前端安全与规范(渔隐)
浅谈前端安全与规范(渔隐)浅谈前端安全与规范(渔隐)
浅谈前端安全与规范(渔隐)
tbmallf2e
 

Similar to 技术交流 支付二代信息安全及其代收付实现 (20)

希望科技研发部变量命名及编码规范
希望科技研发部变量命名及编码规范希望科技研发部变量命名及编码规范
希望科技研发部变量命名及编码规范
 
高性能远程调用解决方案
高性能远程调用解决方案高性能远程调用解决方案
高性能远程调用解决方案
 
Erlang游戏开发
Erlang游戏开发Erlang游戏开发
Erlang游戏开发
 
Glider
GliderGlider
Glider
 
模块一-Go语言特性.pdf
模块一-Go语言特性.pdf模块一-Go语言特性.pdf
模块一-Go语言特性.pdf
 
電腦網路 網路安全
電腦網路 網路安全電腦網路 網路安全
電腦網路 網路安全
 
Internet Security
Internet SecurityInternet Security
Internet Security
 
網路安全
網路安全網路安全
網路安全
 
網路安全
網路安全網路安全
網路安全
 
Brochure ahn lab trusguard utm
Brochure ahn lab trusguard utmBrochure ahn lab trusguard utm
Brochure ahn lab trusguard utm
 
專題總結
專題總結專題總結
專題總結
 
網站設計100步
網站設計100步網站設計100步
網站設計100步
 
Times Ten Training
Times Ten TrainingTimes Ten Training
Times Ten Training
 
Win dbg入门
Win dbg入门Win dbg入门
Win dbg入门
 
Windbg入门
Windbg入门Windbg入门
Windbg入门
 
[系列活動] 手把手教你R語言資料分析實務
[系列活動] 手把手教你R語言資料分析實務[系列活動] 手把手教你R語言資料分析實務
[系列活動] 手把手教你R語言資料分析實務
 
Practical data analysis in R: from data collection to data insight
Practical data analysis in R: from data collection to data insight Practical data analysis in R: from data collection to data insight
Practical data analysis in R: from data collection to data insight
 
Practical Data Analysis in R
Practical Data Analysis in RPractical Data Analysis in R
Practical Data Analysis in R
 
基于Erlang的
基于Erlang的基于Erlang的
基于Erlang的
 
浅谈前端安全与规范(渔隐)
浅谈前端安全与规范(渔隐)浅谈前端安全与规范(渔隐)
浅谈前端安全与规范(渔隐)
 

技术交流 支付二代信息安全及其代收付实现

  • 1. 技术交流 - 二代支付信息安全及其代收付实现 李潜德 2012.7.30 广州金电图腾软件有限公司
  • 2. 问题域 • 什么是电子信息安全 • 支付二代改进了什么 • 改进的理论支持是什么 • 该理论支持有何实现 • 如何学习该实现 • 该实现如何应用到代收付
  • 3. 电子信息安全 1. 确保电子信息在传输、存取和处理过程中,保持其保密性、完整性和可用性,并实现鉴别、授权 、访问控制,抗否认性及可服务性等安全功能。 2. 基本内容:实体安全、运行安全、信息资产安全、人员安全 3. 保证措施:机构安全制度建设(其中密钥管理:生成、存储保护、备份恢复、分发装载、使用更换 、销毁删除、归档终止);相关法律、法规、标准。
  • 4. 从支付接口看安全 - 支付一代 证明接收者能够核实发送者发送了这样的消息,而且只发送了一次。 全国押(还是地方?)密钥 -> 产生 MAC 。 加押字串包含流水号。 1. 完整 - 能够确保消息不被修改 -- OK 2. 鉴别 - 能够确认消息的发送者身份 -- NO 3. 防抵赖 - 能够防止消息发送者抵赖 -- NO 4. 防抵赖 - 能够保证消息不被重放 -- OK
  • 5. 从支付接口看安全 - 支付二代 数字签名。 加签字串包含流水号。 1. 完整 - 能够确保消息不被修改 -- OK 2. 鉴别 - 能够确认消息的发送者身份 -- OK 3. 防抵赖 - 能够防止消息发送者抵赖 -- OK 4. 防抵赖 - 能够保证消息不被重放 -- OK
  • 8. 数字证书认证机构( CA, Certificate Authority ) 负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的 合法性检验的责任。 CA 也拥有一个证书(内含公钥)和私钥。网上的公众用户通过验证 CA 的签字从而信任 CA ,任何人 都可以得到 CA 的证书(含公钥),用以验证它所签发的证书。
  • 9. 数字证书 证书实际是由证书签证机关( CA )签发的 对用户的公钥的认证。包含用户的信息,用 户的公钥,还有 CA 中心对该证书里面的信 息的签名。 常用证书文件后缀名 .cer,.crt,.der - 二进制的 DER 文件格式,不包 含私钥 .pem - 对二进制的 DER 文件格式再用 Base64 编码后的文件,不包含私钥 .p7b,.p7c - PKCS#7 证书格式,仅包含证书 和 CRL 列表信息,不包含私钥 .pfx,p12 - KCS#12 文件 , 包含证书(公钥 )和私钥(受密码保护),以及完整的证书 链信息
  • 10. 证书链 (Certificate Chain) 证书链由两个环节组成—信任锚( CA 证书)环节和 已签名证书环节。自我签名的证书仅有一个环节的长 度—信任锚环节就是已签名证书本身。 证书链可以有任意环节的长度,所以在三节的链中, 信任锚证书 CA 环节可以对中间证书签名;中间证书 的所有者可以用自己的私钥对另一个证书签名。 可以遍历证书链以验证有效性,有效的证书链就构成 了信任链。
  • 11. 根证书 根证书是 CA 认证中心给自己颁发的证书 , 是信任 链的起始点。 安装根证书意味着对这个 CA 认证中心的信任,表 明您对该根证书以下所签发的证书都表示信任,而 技术上则是建立起一个验证证书信息的链条,证书 的验证追溯至根证书即为结束。
  • 12. 证书吊销列表 CRL 一定是被 CA 所签署的,可以使用与签发证书相同的私钥,也可以使用专门的 CRL 签发私钥。 CRL 中包含了被吊销证书的序列号。 证书具有一个指定的寿命,但 CA 可通过称为证书吊销的过程来缩短这一寿命。 CA 发布一个证书吊销 列表 (CRL) ,列出被认为不能再使用的证书的序列号。
  • 14. OpenSSL 简介 - 概览 • 功能丰富且自包含的开源安全工具箱 • 以 C 语言为开发语言
  • 15. OpenSSL 简介 - 关注功能 • 非对称加解密算法 • 数字证书编解码 • 数字证书验证 • PKCS7 标准实现 • PKCS12 个人数字证书格式实现
  • 16. OpenSSL 简介 - 学习方法 • Apps 包含工具源码 • Demos 包含范例源 码
  • 17. OpenSSL 应用 - 初始结束 • 初始化 OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); • 结束 EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); ERR_free_strings();
  • 18. OpenSSL 应用 - 错误处理 • 打印当前错误 ERR_print_errors_fp (gf_log_ptr);
  • 19. OpenSSL 应用 - 内存分配 • 可以记录内存的分配与释放 • 可以基于记录将内存泄露的情况打印出来
  • 20. OpenSSL 应用 - 内存分配 • 打开内存跟踪记录 CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); • 申请内存 gs_msg_buf = OPENSSL_malloc(MSG_MAX_LEN); • 释放内存 OPENSSL_free(gs_msg_buf); • 打印内存泄露 CRYPTO_mem_leaks_fp(arch_trc_get_trc_file()); [13:12:54] 3156 file=digest.c, line=305, thread=3764460, number=104, address=1102B9FB0 [13:11:07] 383 file=mbfe2_acore_app.c, line=222, thread=3764460, number=6291456, address=1102C4FB0 6291560 bytes leaked in 2 chunks
  • 21. OpenSSL 应用 - 抽象 IO • 对常见 IO 的抽象封装 • 可以组成管道
  • 22. OpenSSL 应用 - 抽象 IO- 内存 IO • 从内存中构建 IO inData = BIO_new_mem_buf(s_x509_pem, strlen(s_x509_pem)); • 在其他函数中使用该 IO x509 = PEM_read_bio_X509(inData, NULL, NULL, NULL); • 释放该 IO BIO_free_all(inData);
  • 23. OpenSSL 应用 - 抽象 IO- 嵌套 IO • 从内存中构建 IO out = BIO_new(BIO_s_mem()); • 创建嵌套 IO b64 = BIO_new(BIO_f_base64()); out = BIO_push(b64, out); • 释放该 IO BIO_free_all(out);
  • 24. OpenSSL 应用 -PEM • Privacy Enhanced Mail , OpenSSL 的默认信 息存放方式 • 包含如下信息 1) 内容类型 2) 头信息 3) 信息体
  • 25. OpenSSL 应用 -PEM • CFCA 根证书 -----BEGIN CERTIFICATE-----^M MIICvDCCAiWgAwIBAgIEPPx1qzANBgkqhkiG9w0BAQUFADAgMQswCQYDVQQGEwJD^M TjERMA8GA1UEChMIQ0ZDQSBSQ0EwHhcNMDIwNjA0MDczOTIwWhcNMjIwNjA0MDgw^M OTIwWjAgMQswCQYDVQQGEwJDTjERMA8GA1UEChMIQ0ZDQSBSQ0EwgZ8wDQYJKoZI^M hvcNAQEBBQADgY0AMIGJAoGBALjj9EbWFRz6rj4a42KpSB+jPqoHnkjmr3S69P4A^M icz9r6ZfFat1SvjJAG4XjB69ejGczrP2Acp3JVyH3jDMXSa4EfEfw/Erom1ILaWy^M jKTl/Cs78oJMjGyiZT5CJ14gH6o9rVYMEr2FjH6a7SJKJ/P/YBiQzNh6h97gynIy^M J5ChAgMBAAGjggEBMIH+MBEGCWCGSAGG+EIBAQQEAwIABzBCBgNVHR8EOzA5MDeg^M NaAzpDEwLzELMAkGA1UEBhMCQ04xETAPBgNVBAoTCENGQ0EgUkNBMQ0wCwYDVQQD^M EwRDUkwxMCsGA1UdEAQkMCKADzIwMDIwNjA0MDczOTIwWoEPMjAyMjA2MDQwODA5^M MjBaMAsGA1UdDwQEAwIBBjAfBgNVHSMEGDAWgBQAmjTyUflTFGF0bnKhBt7HgXAb^M vDAdBgNVHQ4EFgQUAJo08lH5UxRhdG5yoQbex4FwG7wwDAYDVR0TBAUwAwEB/zAd^M BgkqhkiG9n0HQQAEEDAOGwhWNi4wOjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEA^M Jv+gsBZv4egVVt7qPYUM8M0rfT2TjUd/vm7l7kmfGHLz2hJR2fMhgMXo8sxPBA6D^M L3ZW08X+UA5Gsa34enwtkDEVTe1Nvpz6L+W1C9hWpzyKsK0HQbrC5xTLAcEl7nlt^M Zb/JN44RbcevYcdAt3SyOAaoOtGljBQwFI0TFdMwHrg=^M -----END CERTIFICATE-----^M
  • 26. OpenSSL 应用 -PEM- 证书 • 读取证书 x509 = PEM_read_bio_X509(inData, NULL, NULL, NULL); • 保存证书 err = PEM_write_bio_X509(bMem, x509);
  • 27. OpenSSL 应用 - 证书 • 从证书获取公钥 pubkey=X509_get_pubkey(x509); • 从证书获取颁发者 name = X509_get_issuer_name(signer); • 释放证书结构 X509_free(g_x509);
  • 28. OpenSSL 应用 - 证书仓库 • 用于简化证书链等操作
  • 29. OpenSSL 应用 - 证书仓库 • 搭建证书仓库 g_X509_store = X509_STORE_new(); • 设置检查所有证书是否撤销 X509_STORE_set_flags(g_X509_store, X509_V_FLAG_CRL_CHECK); • 设置证书链检查深度 X509_STORE_set_depth(g_X509_store, 10); • 设置回调函数,在回调函数中检查是否忽略错误 X509_STORE_set_verify_cb_func(g_X509_store, _verify_callback);
  • 30. OpenSSL 应用 - 证书仓库 • 指定证书搜索方法 lookup=X509_STORE_add_lookup(g_X509_store, X509_LOOKUP_hash_dir()); • 指定证书来源 sprintf(szCACertFileName, "%s/keystore/cacerts", g_home); err = X509_LOOKUP_add_dir(lookup,szCACertFileName,X509_FILETYPE_PEM);
  • 31. OpenSSL 应用 -PKCS12 • 一种交换数字证书的加 密标准 • 用于描述个人身份信息 用户公钥、私钥、证书等
  • 32. OpenSSL 应用 -PKCS12 • 读取 PKCS12 信息 p12 = d2i_PKCS12_fp(fp, NULL); • 解析 PKCS12 信息 PKCS12_parse(p12, gf_PKCS12Password, &g_privkey, &g_x509, NULL) • 释放 PKCS12 内部结构 PKCS12_free(p12);
  • 33. OpenSSL 应用 -EVP • 对编解码、摘要、加解密等提供统一函数 入口
  • 34. OpenSSL 应用 -EVP-Base64 • 定义并初始化编码上下文 EVP_ENCODE_CTX ectx; EVP_EncodeInit(&ectx); • 不断进行编码输出 EVP_EncodeUpdate(&ectx, t, &ebuflen, f, n); • 结束编码 EVP_EncodeFinal(&ectx, t+ebuflen, &ebuflen);
  • 35. OpenSSL 应用 -EVP-Base64 • 定义并初始化解码上下文 EVP_ENCODE_CTX ectx; EVP_DecodeInit(&ectx); • 不断进行解码输出 EVP_DecodeUpdate(&ectx, t, &ebuflen, f, n); • 结束解码 EVP_DecodeFinal(&ectx, t+ebuflen, &ebuflen);
  • 36. OpenSSL 应用 -EVP-Base64 • 直接编码 EVP_EncodeBlock(signB64,sign,signLen); • 直接解码 len = EVP_DecodeBlock(sign, signB64, strlen(signB64));
  • 37. OpenSSL 应用 -EVP-Base64 • 最大区别 第一种每 64 位会自动加上换行符 (n) ,方便阅读。 第二种一长串输出。
  • 38. OpenSSL 应用 -EVP-MD5 • 计算 MD5 err = EVP_Digest(pDetailBgn, pTmp - pDetailBgn, md, NULL, EVP_md5(), NULL);
  • 39. OpenSSL 应用 -EVP- 裸签 • 裸签 EVP_MD_CTX md_ctx; EVP_SignInit (&md_ctx, EVP_sha1()); EVP_SignUpdate (&md_ctx, pOrgData, nOrgDataSize); signDataSize = *pSignDataSize; err = EVP_SignFinal (&md_ctx, pSignData, &signDataSize, g_privkey); EVP_MD_CTX_cleanup(&md_ctx);
  • 40. OpenSSL 应用 -EVP- 裸验签 • 裸验签 EVP_MD_CTX md_ctx; EVP_VerifyInit(&md_ctx, EVP_sha1()); EVP_VerifyUpdate(&md_ctx, pOrgData, nOrgDataSize); err = EVP_VerifyFinal (&md_ctx, pSignData, nSignDataSize, pubkey); EVP_MD_CTX_cleanup(&md_ctx);
  • 41. OpenSSL 应用 -EVP- 其他 • 释放公私钥 EVP_PKEY_free(g_privkey);
  • 42. OpenSSL 应用 -PKCS7 • 加密消息的语法标准,由 RSA 安全体系在公钥加密系统中 交换数字证书产生的一种加密标准。
  • 43. OpenSSL 应用 -PKCS7 • P7 分离式签名 p7 = PKCS7_sign(g_x509, g_privkey, NULL, in, PKCS7_DETACHED | PKCS7_NOATTR); • 获取 P7 字串 err = i2d_PKCS7_bio(out,p7); • 释放 P7 内部结构 PKCS7_free(p7);
  • 44. OpenSSL 应用 -PKCS7 • 从 P7 字串得到 P7 内部结构 p7 = d2i_PKCS7_bio(inSign, NULL); • 验证 err = PKCS7_verify(p7, NULL, g_X509_store, inData, NULL, 0); • 释放 P7 内部结构 PKCS7_free(p7);
  • 45. OpenSSL 工具 -CRL 格式转换 从 DER 格式转换到 PEM 格式 openssl crl -inform DER -in crl.crl -outform PEM -out crl.pem
  • 46. OpenSSL 工具 - 证书格式转换 从 DER 格式转换到 PEM 格式 openssl x509 -inform DER -in der.cer -outform PEM -out pem.cer
  • 48. 代收付实现 - 登录 - 接口 序 加签 或 报文要素 <XML Tag> 属性 类型 备注 号 要素 Message root <LoginReq> [1..1] LoginRequest GroupHeader <GrpHdr> [1..1] 【业务头】 √ LoginInformation <LoginInf> [1..1] --LoginOperationType <LoginOprTp> [1..1] LoginOperationTypeCode 禁止中文 √ 操作类型
  • 49. 代收付实现 - 登录 - 接口 加签 序号 OR 要素名称 XML Tag 属性 类型 备注 要素 MessageIdentification 报文标识号 <MsgId> [1..1] Max35Text 禁止中文 √ CreationDateTime 报文发送时间 <CreDtTm> [1..1] ISODateTime 禁止中文 √ InstructingParty <InstgPty> [1..1] --InstructingDirectParty 发起直接参与机构 <InstgDrctPty> [1..1] Max14Text 禁止中文 √ --InstructingParty 发起参与机构 <InstgPty> [1..1] Max14Text 禁止中文 √ InstructedParty <InstdPty> [1..1] --InstructedDirectParty 接收直接参与机构 <InstdDrctPty> [1..1] Max14Text 禁止中文 √ --InstructedParty 接收参与机构 <InstdPty> [1..1] Max14Text 禁止中文 √ SystemCode 系统编号 <SysCd> [1..1] SystemCode 禁止中文 √ Remark <Rmk> [0..1] Max256Text 允许中文 备注
  • 50. 代收付实现 - 登录 - 配置加签报 文 static MSGSIGNMAPPING msgSignMapping[] = { …. /* 签到签退请求报文 */ { "ccms.805.001.02", 1, NULL, xmlEntry_ccms_805}, …. };
  • 51. 代收付实现 - 登录 - 配置加签要 素 /* 签到签退请求报文 */ static XML_PATH_ENTRY xmlEntry_ccms_805[] = { {"/Document/LoginReq/GrpHdr/MsgId", "", ""}, {"/Document/LoginReq/GrpHdr/CreDtTm", "", ""}, {"/Document/LoginReq/GrpHdr/InstgPty/InstgDrctPty","", ""}, {"/Document/LoginReq/GrpHdr/InstgPty/InstgPty","", ""}, {"/Document/LoginReq/GrpHdr/InstdPty/InstdDrctPty","", ""}, {"/Document/LoginReq/GrpHdr/InstdPty/InstdPty","", ""}, {"/Document/LoginReq/GrpHdr/SysCd","", ""}, {"/Document/LoginReq/LoginInf/LoginOprTp","", ""}, {"","", ""} };
  • 52. 代收付实现 - 登录 - 报文实例 {H:02906581000018 BEPS BEPS20120425175450XMLccms.805.001.02 2012042 5MF100000001220120425MF10000000123U }^M {S:GHR4geKYh5mtnu9yEjrxpfX7inV7FyFHp0ErN2yI4bl/DJvn1udv/o2QeTpfh7+mLLhm2TQi5oX4AxjzdcqFhQE8uB1mfWSGgjJjcFOWbPXa10XLBxSuYMm/tFWdc38uJHBzFuX6wYogsaiXLmQV5bvkU5 18MEpQwZBTz5ZvjMU=}^M <?xml version="1.0" encoding="UTF-8"?>^M <Document xmlns="urn:cnaps:std:ccms:2010:tech:xsd:ccms.805.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">^M <LoginReq>^M <GrpHdr>^M <MsgId>2011110901000004</MsgId>^M <CreDtTm>2012-04-25T17:54:50</CreDtTm>^M <InstgPty>^M <InstgDrctPty>906581000018</InstgDrctPty>^M <InstgPty>906581000018</InstgPty>^M </InstgPty>^M <InstdPty>^M <InstdDrctPty>NT00</InstdDrctPty>^M <InstdPty>NT00</InstdPty>^M </InstdPty>^M <SysCd>BEPS</SysCd>^M <Rmk> 骞垮穅揲 ^ 佣琛 ^ 嚏 ^ 缘瀛 ^ 戌籢隅甞卒腑蹇 ^ 娩唬鎊远浠 ^ 劐癪祥葭錨劝绛鹃 ^ 繼 /Rmk>^M </GrpHdr>^M <LoginInf>^M <LoginOprTp>OT00</LoginOprTp>^M </LoginInf>^M </LoginReq>^M </Document>^M
  • 53. 代收付实现 - 登录 - 报文加签串 [
  • 54. 代收付实现 - 裸签名 int RawSign(int nSocketFd, unsigned char* pOrgData, int nOrgDataSize, char* sCertDN, unsigned char* pSignData, int* pSignDataSize) { …. /* 用私钥对数据进行裸签 */ EVP_SignInit (&md_ctx, EVP_sha1()); EVP_SignUpdate (&md_ctx, pOrgData, nOrgDataSize); signDataSize = *pSignDataSize; err = EVP_SignFinal (&md_ctx, pSignData, &signDataSize, g_privkey); /* 释放资源,避免内存泄露 */ EVP_MD_CTX_cleanup(&md_ctx); …. * pSignDataSize = signDataSize; return (0); }
  • 56. 代收付实现 - 继续了解 可参考的独立程序 SecureDemo SecureTool SVN 路径: http://56.16.32.156:8001/svn/code/mbfe2/Source/Main/src/app/secure
  • 57. 参考资料 • 《 openssl 编程 .pdf 》 - 赵春平 • mbfe2dev - 金电图腾 • openssl-0.9.8u.tar.gz - www.openssl.org • 公钥密码技术讲义 - 四川大学计算机网络与安全研究所 • 信息安全与加密解密核心技术 - 黄元飞 • 百度百科 • 维基百科 • 二代接口文档