More Related Content Similar to 技术交流 支付二代信息安全及其代收付实现 (20) 技术交流 支付二代信息安全及其代收付实现2. 问题域
• 什么是电子信息安全
• 支付二代改进了什么
• 改进的理论支持是什么
• 该理论支持有何实现
• 如何学习该实现
• 该实现如何应用到代收付
3. 电子信息安全
1. 确保电子信息在传输、存取和处理过程中,保持其保密性、完整性和可用性,并实现鉴别、授权
、访问控制,抗否认性及可服务性等安全功能。
2. 基本内容:实体安全、运行安全、信息资产安全、人员安全
3. 保证措施:机构安全制度建设(其中密钥管理:生成、存储保护、备份恢复、分发装载、使用更换
、销毁删除、归档终止);相关法律、法规、标准。
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) ,列出被认为不能再使用的证书的序列号。
15. OpenSSL 简介 - 关注功能
• 非对称加解密算法
• 数字证书编解码
• 数字证书验证
• PKCS7 标准实现
• PKCS12 个人数字证书格式实现
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);
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
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);
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);
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);
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));
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);
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
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);
}
57. 参考资料
• 《 openssl 编程 .pdf 》 - 赵春平
• mbfe2dev - 金电图腾
• openssl-0.9.8u.tar.gz - www.openssl.org
• 公钥密码技术讲义 - 四川大学计算机网络与安全研究所
• 信息安全与加密解密核心技术 - 黄元飞
• 百度百科
• 维基百科
• 二代接口文档