密钥管理方法DUKPT的OpenSSL代码实现Demo

目录

1 DUKPT简介

2 基本概念

2.1 BDK

2.2 KSN

2.3 IPEK

2.4 FK

2.5 TK

3 工作流程

3.1 密钥注入过程

3.2 交易过程

3.3 BDK派生IPEK过程

3.4 IPEK计算FK过程

4 演示Demo

4.1 开发环境

4.2 功能介绍

4.3 下载地址

5 在线工具

6 标准下载


1 DUKPT简介

        DUKPT(Derived Unique Key Per Transaction)是被ANSI定义的一套密钥管理体系和算法,用于解决金融支付领域的信息安全传输中的密钥管理问题,应用于对称密钥加密MAC、PIN等数据安全方面。保证每一次交易流程使用唯一的密钥,采用一种不可逆的密钥转换算法,使得无法从当前交易数据信息破解上一次交易密钥。要求收单行与终端必须同步支持该项密钥管理技术。由交易发起端点(S-TRSM,如POS、ATM)与交易接收端点(R-TRSM,如收单行)两部分组成。

注:TRSM(Tamper-Resistant Security Module)是一个具备阻止攻击能力的安全模块。

        以下是 DUKPT的一些关键特点:

  • 唯一性:DUKPT为每个交易生成一个唯一的加密密钥,确保即使相同的主密钥在不同交易中使用,也能产生不同的派生密钥。

  • 分散:DUKPT使用一种称为分散的技术,通过将密钥按照一定规则扩展为不同的密钥,以增加密钥的安全性。

  • 保密性:DUKPT通过不存储或传输主密钥的完整值,而是使用一个初始的主密钥派生出每个交易的密钥,从而增加了密钥的保密性。

  • 动态变化:DUKPT可以动态地变化,以适应不同的交易条件。这使得攻击者更难预测下一个派生密钥。

  • 逆推困难性:由于DUKPT的分散和动态性,逆推派生密钥以获取原始主密钥是非常困难的。

  • 用途:DUKPT主要用于保护磁条卡数据、PIN(个人身份号码)加密和其他金融交易中的密钥管理。

2 基本概念

2.1 BDK

        BDK(Base Derived Key)是用于派生其他密钥的基础密钥。在金融行业和加密领域中,BDK通常是一个16字节(128位)的密钥,用于生成其他密钥,如PIN加密密钥、MAC密钥等。BDK的安全性对整个加密系统至关重要,因为它作为生成其他关键的基础。通常,BDK是在加密设备的安全环境中生成和存储的,以确保其机密性。密钥派生函数将BDK与其他参数结合使用,生成用于特定加密目的的派生密钥。这有助于提高密钥的安全性,因为实际用于加密的密钥是通过派生而来的,而不是直接使用BDK。BDK在加密系统中扮演着关键的角色,它的安全性直接影响整个加密系统的强度。因此,保护和管理BDK是确保整个加密体系安全的一个重要方面。

2.2 KSN

        KSN(Key Serial Number)是用于标识加密设备和交易的一种格式化序列号,由“密钥标识40bit+设备标识19bit+密钥计数器21bit”组成。KSN通常与加密操作一起使用,特别是在金融交易领域,用于生成派生密钥和跟踪加密设备的使用情况。KSN 的生成和使用是为了追踪和管理加密设备,确保其唯一性和完整性。在金融交易中,KSN 通常用于生成派生密钥,以确保每个交易都使用一个唯一的密钥,提高加密的安全性。

2.3 IPEK

        IPEK(Initial Pin Encrypt Key)是金融领域中用于加密和解密用户个人身份号码(PIN)的密钥。IPEK通常是从BDK(Base Derivation Key)派生而来,通过一个特定的密钥派生函数生成。在金融交易中,IPEK用于保护用户的PIN,确保其传输和存储的安全性。

2.4 FK

        FK 通常指 “Future Key”。在密码学和安全领域中,“Future Key” 指代在将来某个时刻用于加密或其他安全目的的密钥。在金融领域或其他需要密钥管理的地方,“Future Key” 是一个临时的术语,用于表示将来用于某些目的的密钥。这可能包括 PIN 密钥、MAC 密钥或其他加密密钥。FK 可能是从某个初始密钥派生出来,以确保密钥的定期轮换或更新。

2.5 TK

        “TK” 通常指 “Transaction Key”,在金融领域中,这是一个用于保护特定交易的密钥,是 “Future Key” xor 分散向量得到的工作密钥TK,例如:

  • PIN 密钥的分散向量:00000000000000FF00000000000000FF

  • MAC 密钥的分散向量:000000000000FF00000000000000FF00

3 工作流程

3.1 密钥注入过程

  1. Acquirer 给 POS 灌输 BDK

  2. BDK + KSN(EC=0) 派生出 IPEK

  3. IPEK + KSN 派生出 21 个 Future Key,分别存在 POS 的 21 个寄存器中:

    1. IPEK + KSN(EC=1) -> FK1,存在寄存器 1

    2. IPEK + KSN(EC=2) -> FK2,存在寄存器 2

    3. IPEK + KSN(EC=21) -> FK21,存在寄存器 21

  4. 销毁 BDK 和 IPEK

3.2 交易过程

        一笔交易从一个寄存器中取出一个 FK,根据应用 xor 分散向量得到的工作密钥TK进行使用。

          假设取出寄存器1中的 FK1(根据应用 xor 分散向量得到的工作密钥TK)使用,交易处理完成后:

  • KSN 加 1 后变成 KSN(EC=22)

  • FK1 + KSN(EC=22) -> FK22,替换掉 FK1 存在寄存器 1 中 以此类推依次重复使用这 21 个寄存器中的 FK。

3.3 BDK派生IPEK过程

  (1)将KSN右对齐复制到一个10字节的寄存器中

  (2)将此10字节寄存器的21个最低有效位设置为零

  (3)取这个10字节寄存器的8个最高有效字节作为输入数据,使用BDK作为加密密钥,调用3DES的CBC模式算法(其中iv向量设置为全0)进行加密

  (4)使用步骤3生成的密文作为初始密钥IPEK的左半部分

  (5)从步骤2的10字节寄存器中取出8个最高有效字节,并使用BDK与BDK掩码向量(0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00)的异或结果作为加密密钥,调用3DES的CBC模式算法(其中iv向量设置为全0)进行加密

  (6)使用步骤5生成的密文作为初始密钥IPEK的右半部分

/***********************************************************
    功    能:BDK派生IPEK
    参    数:ipek16 - 输出,IPEK,16字节
              bdk16 - 输入,BDK,16字节
              ksn10 - 输入,KSN,10字节
    返    回:
***********************************************************/
static const u8 BDK_MASK[16] = {0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00};

void DukptGenerateIpek( _OUT u8 * const ipek16, 
                _IN u8 * const bdk16, 
                _IN u8 * const ksn10 ) 
{
        u8 partKsn[8];
        memcpy( partKsn, ksn10, 8);
        partKsn[7] &= 0xE0;
        {
                u8 leftIpek[24];
                DES_key_schedule SchKey[2];
                DES_set_key_unchecked((const_DES_cblock *)&bdk16[0], &SchKey[0]);
                DES_set_key_unchecked((const_DES_cblock *)&bdk16[8], &SchKey[1]);
                DES_cblock iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                DES_ede3_cbc_encrypt( (unsigned char*)partKsn, (unsigned char*)leftIpek, 8,
                                &SchKey[0], &SchKey[1], &SchKey[0],
                                &iv, DES_ENCRYPT);
                memcpy( &ipek16[0], leftIpek, 8 );
        }

        u8 derivedBdk[16];
        for (fu8 i = 0; i < 16; i++) {
                derivedBdk[i] = bdk16[i] ^ BDK_MASK[i];
        }
        {
                u8 rightIpek[24];
                DES_key_schedule SchKey[2];
                DES_set_key_unchecked((const_DES_cblock *)&derivedBdk[0], &SchKey[0]);
                DES_set_key_unchecked((const_DES_cblock *)&derivedBdk[8], &SchKey[1]);
                DES_cblock iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
                DES_ede3_cbc_encrypt( (unsigned char*)partKsn, (unsigned char*)rightIpek, 8,
                                &SchKey[0], &SchKey[1], &SchKey[0],
                                &iv, DES_ENCRYPT);
                memcpy( &ipek16[8], rightIpek, 8 );
        }
}

3.4 IPEK计算FK过程

变量说明:

        R8: 8字节寄存器

        R8A: 8字节寄存器

        R8B: 8字节寄存器

        R3: 21位寄存器

        SR: 21位移位寄存器

        KSNR: 8字节寄存器,从输入设备接收到的密钥序列号的最右8字节

        IKEY: 16字节寄存器,加密密钥初始加载到输入设备

        CURKEY: 16字节寄存器;在算法完成时,它包含当前事务中用于加密的工作密钥FK

处理过程如下:

        (1)将IKEY复制到CURKEY中

        (2)将KSNR复制到R8

        (3)清除R8的21个最右边的位

        (4)将KSNR的21个最右边的位复制到R3中

        (5)设置SR的最左位,清除其他20位

"TAG1"

          (1)SR 与运算 R3,并判断结果是否包含1?如果是,请转到“TAG2”

          (2)SR 或运算 R8,并将结果存储在R8中

          (3)R8 异或运算 CURKEY的右半8字节,并将结果存储在R8A中

          (4)使用CURKEY的左半8字节作为密钥,对R8A进行DEA加密,并将结果存储在R8A中

          (5)R8A 异或运算 CURKEY的右半8字节,并将结果存储在R8A中

          (6)CURKEY 异或运算 掩码向量(0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00),并将结果存储到CURKEY 中

          (7)R8 异或运算 CURKEY的右半8字节,并将结果存储在R8B中

          (8)使用CURKEY的左半8字节作为密钥,对R8B进行DEA加密,并将结果存储在R8B中

          (9)R8B 异或运算 CURKEY的右半8字节,并将结果存储在R8B中

          (10)将R8A储存在CURKEY的右半部

          (11)将R8B储存在CURKEY的左半部

"TAG2”

        (1)将SR向右移动一比特

        (2)如果SR不等于零(如果“1”位没有被移除),请转到“TAG1”,否则结束

/***********************************************************
    功    能:IPEK计算FK
    参    数:ipek_drvd16- 输出,FK,16字节
              ksn10 - 输入,KSN,10字节
              bdk16 - 输入,BDK,16字节
    返    回:
***********************************************************/
void FkFromIpek( _OUT u8 * const ipek_drvd16, 
                _IN u8 * const ksn10,
                _IN u8 * const ipek16 ) {
        memcpy( ipek_drvd16, ipek16, 16 );
        
        u8 counter[8];
        memcpy( counter, &ksn10[2], 8 );      
        counter[0] = 0x00;
        counter[1] = 0x00;
        counter[2] = 0x00;
        counter[3] = 0x00;
        counter[4] = 0x00;
        counter[5] &= 0x1F;
        counter[6] &= 0xFF;
        counter[7] &= 0xFF;

        u8 serial[8];
        memcpy( serial, &ksn10[2], 8 );      
        serial[5] &= 0xE0;
        serial[6] &= 0x00;
        serial[7] &= 0x00;
        
        u8 shiftr[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00};    
        u8 crypto_register_1[8];
        memcpy(crypto_register_1, serial, 8);   
        u64 intShiftr = 16*65536; 
        while( intShiftr > 0 ) {
                u8 temp[8];          
                And( temp, shiftr, counter, 8 );          
                if( HaveOnes(temp, 8) ) {
                        Or(serial, serial, shiftr, 8);        
                        u8 crypto_register_2[8];
                        Xor(crypto_register_2, serial, &ipek_drvd16[8], 8 );
                        {
                                u8 crypto_register_2_temp[8];
                                DES_key_schedule SchKey;
                                DES_set_key_unchecked((const_DES_cblock *) &ipek_drvd16[0], &SchKey);
                                DES_ecb_encrypt((const_DES_cblock *) crypto_register_2, (const_DES_cblock *) crypto_register_2_temp, &SchKey, DES_ENCRYPT);                              
                                memcpy(crypto_register_2, crypto_register_2_temp, 8);
                        }                   
                        Xor( crypto_register_2, crypto_register_2, &ipek_drvd16[8], 8);                    
                        Xor( ipek_drvd16, ipek_drvd16, BDK_MASK, 16 );                        
                        Xor( crypto_register_1, serial, &ipek_drvd16[8], 8 );                        
                        {
                                u8 crypto_register_1_temp[8];
                                DES_key_schedule SchKey;
                                DES_set_key_unchecked((const_DES_cblock *) &ipek_drvd16[0], &SchKey);
                                DES_ecb_encrypt((const_DES_cblock *) crypto_register_1, (const_DES_cblock *) crypto_register_1_temp, &SchKey, DES_ENCRYPT);                                
                                memcpy(crypto_register_1, crypto_register_1_temp, 8);
                        }                      
                        Xor( crypto_register_1, crypto_register_1, &ipek_drvd16[8], 8 );                        
                        memcpy( &ipek_drvd16[0], crypto_register_1, 8 );
                        memcpy( &ipek_drvd16[8], crypto_register_2, 8 );
                }            
                intShiftr >>= 1;            
                shiftr[7] = (intShiftr >> 0)  & 0xFF;
                shiftr[6] = (intShiftr >> 8)  & 0xFF;
                shiftr[5] = (intShiftr >> 16) & 0xFF;
                shiftr[4] = (intShiftr >> 24) & 0xFF;
                shiftr[3] = (intShiftr >> 32) & 0xFF;
                shiftr[2] = (intShiftr >> 40) & 0xFF;
                shiftr[1] = (intShiftr >> 48) & 0xFF;
                shiftr[0] = (intShiftr >> 56) & 0xFF;
        }
}

4 演示Demo

4.1 开发环境

  • OpenSSL 1.0.2l

  • Visual Studio 2015

  • Windows 10 Pro x64

4.2 功能介绍

        演示程序主界面如下图所示,包括BDK计算密钥、BDK派生IPEK,IPEK计算密钥,KSN自增等功能。

4.3 下载地址

        密钥管理方法DUKPT的OpenSSL代码实现Demo

5 在线工具

        MAC、PIN、DUKPT算法

6 标准下载

        ANSI X9.24-1-2009

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/903317.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DEVOPS: 集群伸缩原理

概述 阿里云 K8S 集群的一个重要特性&#xff0c;是集群的节点可以动态的增加或减少有了这个特性&#xff0c;集群才能在计算资源不足的情况下扩容新的节点&#xff0c;同时也可以在资源利用 率降低的时候&#xff0c;释放节点以节省费用理解实现原理&#xff0c;在遇到问题的…

Linux系统解压分卷压缩文件的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【CUDA代码实践03】m维网格n维线程块对二维矩阵的索引

文章目录 一、数据存储方式二、二维网格二维线程块三、二维网格一维线程块四、一维网格一维线程块 为了方便下次找到文章&#xff0c;也方便联系我给大家提供帮助&#xff0c;欢迎大家点赞&#x1f44d;、收藏&#x1f4c2;和关注&#x1f514;&#xff01;一起讨论技术问题&am…

低功耗4G模组:FTP应用示例

一、FTP 概述 FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09; 是 TCP/IP 协议组中的协议之一。 FTP协议包括两个组成部分&#xff0c;其一为FTP服务器&#xff0c;其二为FTP客户端。 其中FTP服务器用来存储文件&#xff0c;用户可以使用FTP客户…

鸿蒙UI开发——基于组件安全区方案实现沉浸式界面

1、概 述 本文是接着上篇文章 鸿蒙UI开发——基于全屏方案实现沉浸式界面 的继续讨论。除了全屏方案实现沉浸式界面外&#xff0c;我们还可以使用组件安全区的方案。 当我们没有使用setWindowLayoutFullScreen()接口设置窗口为全屏布局时&#xff0c;默认使用的策略就是组件安…

智慧税务管理:金融企业报税效率与合规性提升

前言 在数字化浪潮席卷全球的今天&#xff0c;金融行业正面临前所未有的挑战与机遇。如何在复杂的税务环境中保持合规并提高效率&#xff0c;已成为每个金融企业的重中之重。今天小编就为大家介绍一下如何通过借助智能税务平台&#xff0c;实现税务管理的智能化革新&#xff0…

Docker 常用命令全解析:提升对雷池社区版的使用经验

Docker 常用命令解析 Docker 是一个开源的容器化平台&#xff0c;允许开发者将应用及其依赖打包到一个可移植的容器中。以下是一些常用的 Docker 命令及其解析&#xff0c;帮助您更好地使用 Docker。 1. Docker 基础命令 查看 Docker 版本 docker --version查看 Docker 运行…

华为OD机试 - 无向图染色(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

Python+pandas读取Excel将表头为键:对应行为值存为字典—再转json

目录 专栏导读1、库的介绍2、库的安装3、核心代码4、方法1:5、方法2总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自…

摸鱼小工具-窗口隐藏透明

摸鱼小工具-窗口隐藏透明 介绍 就很简单的一个工具&#xff0c;鼠标移上去显示&#xff0c;鼠标离开就透明。具体看图。 源码以及下载地址

vue封装信号强度

图标下载链接: https://pan.baidu.com/s/1828AidkCKU1KTkw1SvBwQg?pwd4k7n 共五格信号 信号5为绿色&#xff0c;信号4为绿色&#xff0c;信号3为黄色&#xff0c;信号2为黄色&#xff0c;信号1为红色&#xff0c;信号0为灰色。 子组件 /components/SignalStrength/index.vu…

使用常数指针作为函数参数

在main.cpp里输入程序如下&#xff1a; #include <iostream> //使能cin(),cout(); #include <iomanip> //使能setbase(),setfill(),setw(),setprecision(),setiosflags()和resetiosflags(); //setbase( char x )是设置输出数字的基数,如输出进制数则用setbas…

简易了解Pytorch中的@ 和 * 运算符(附Demo)

目录 1. 基本知识2. 3. * 1. 基本知识 在 PyTorch 中&#xff0c; 和 * 运算符用于不同类型的数学运算&#xff0c;具体是矩阵乘法和逐元素乘法 基本知识 运算符功能适用场景示例矩阵乘法&#xff08;或点乘&#xff09;用于执行线性代数中的矩阵乘法C A B&#xff0c;其中…

VulkanTutorial(8·Shader modules)

Shader modules 与早期的API不同&#xff0c;Vulkan中的着色器代码必须以字节码格式指定&#xff0c;而不是人类可读的语法&#xff0c;如GLSL和HLSL。这种字节码格式称为SPIR-V它是一种可用于编写图形和计算着色器的格式 使用像SPIR-V这样简单的字节码格式&#xff0c;不会面…

读数据工程之道:设计和构建健壮的数据系统23批量获取的考虑因素

1. 批量获取的考虑因素 1.1. 批量获取&#xff0c;通常是获取数据的一种便捷方式 1.1.1. 通过从源系统中抽取一个数据子集&#xff0c;根据时间间隔或累积数据的大小来获取数据 1.2. 基于时间间隔的批量获取在传统ETL的数据仓库中很普遍 1.2.1. 每天在非工作时间&#xff0…

Cyber​​Panel upgrademysqlstatus 远程命令执行漏洞(QVD-2024-44346)

0x01 产品简介 CyberPanel是一个开源的Web控制面板,它提供了一个用户友好的界面,用于管理网站、电子邮件、数据库、FTP账户等。CyberPanel旨在简化网站管理任务,使非技术用户也能轻松管理自己的在线资源。 0x02 漏洞概述 该漏洞源于upgrademysqlstatus接口未做身份验证和…

【形态学 - 击中-击不中变换(很多都讲得不直观不清楚,甚至是错的,我来个通俗易懂的)】

简单描述过程&#xff1a; 一般的目标匹配是&#xff0c;知道目标长什么样&#xff0c;用这个模板去匹配。这里还知道目标周围环境长什么样。 如何把环境的信息加进来用来帮助匹配呢。这个就是击中-击不中联合匹配了。 就是用亮图去匹配目标。 再用暗图去匹配背景。 两个联合起…

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

单细胞数据分析(四):细胞亚型注释

文章目录 介绍加载R包导入数据细胞簇可视化细胞簇标记基因细胞识别输出结果系统信息介绍 单细胞细胞亚型注释是指在单细胞聚类分析后,对每个聚类得到的细胞群体进行生物学意义上的分类和识别的过程。这一步骤的目的是为了确定每个细胞群体对应的具体细胞类型或状态,从而更好…

CI/CD 的原理

一、CI/CD 的概念 CI/CD是一种软件开发流程&#xff0c;旨在通过自动化和持续的集成、测试和交付实现高质量的软件产品。 CI(Continuous Integration)持续集成 目前主流的开发方式是协同开发&#xff0c;即多位开发人员同事处理同意应用不同模块或功能。 如果企业在同一时间将…