1、PIN

PIN(Personal identification Number),即个人密码,是在联机交易中识别持卡人身份合法性的数据信息,在计算机和网络系统中任何环节不允许PIN以明文的格式出现

PIN规定为4~12位数字,越长越安全,但是从易用的角度考虑不应该超过6位,所以目前的银行卡密码都是6位。但是6位不是唯一的,银行卡密码完全可以支持更少或更多位数。

关于PIN的长度,Wiki上给我们讲了一个小故事:ATM的发明者John Shepherd-Barron最初设想是使用6位长度的密码,但是他的妻子只能记住4位数字,所以国外很多地方是使用4位长度PIN的。毛主席教育我们:妇女能顶半边天。女人是伟大的,女人总在不经意间改变历史。

要对pin进行加密时,由于pin长度一般为6位,不符合加密算法的固定分组长度要求,所以需要对pin进行填充使之达到一个分组的长度,然后加密计算从而保证pin的机密性,填充后的PIN的分组数据块称之为PINBLOCK

PINBLOCK一般用于银行卡取款密码的加密传输处理过程中,遵循ANSI X.98规范,该规范被目前主流的卡组织所接受,包括中国银联。

2、PAN

PAN  :主账户号码 (Primary Account Number的缩写),ISO 9564中定义:发行者分配的号码,由发行者识别号码、个人账户标识和ISO/IEC 7812-1中规定的校验数字组成,用于识别发卡机构和持卡人。详见银行卡号的编码规则及校验。

3、PIN block

PIN 格式块。

ISO 9564标准中定义了5种格式,Format 0,Format 1, Format 2, Format 3,Format 4。

3.1、Format 0 PIN block

由PIN域 和 PAN域 异或 得到。

  • PIN域 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1位(1~4bit):固定值0x0(0000)
  • 第2位(5~8bit):PIN长度,取值范围0x4(0100) ~ 0xC(1100)
  • 第3~16位(9~64bit):PIN,不足14位右补0xF(1111),因为PIN最多12位,所以最后2位一定是0xFF(1111,1111)
  • PAN域 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1~4位(1~16bit):固定值0x0000(0000,0000,0000,0000)
  • 第5~16位(17~64bit):PAN去掉最右边1位校验数字后,从右边数12位,不足12位左补0x0(0000)

以银行卡号6225760008219524,密码123456为例:

代码示例:

/*** Format 0 PIN block* * @param PIN 密码* @param PAN 账号* @return Format 0 PIN block 十六进制字符串*/
private static String format0(String PIN, String PAN) {// PIN域,64bit,16位十六进制数字// 固定值0x0 + PIN长度 + PIN(不足14位右补F)String PINField = "0"+ Integer.toHexString(PIN.length())+ String.format("%-14s", PIN).replace(' ', 'F');// PAN域,64bit,16位十六进制数字// 固定值0x0000 + PAN,去掉校验数字,从右边数12位,不足12位左补0x0String PANWithoutCheckDigit = PAN.substring(0, PAN.length() - 1);String PANField = "0000"+ (PANWithoutCheckDigit.length() > 12 ? PANWithoutCheckDigit.substring(PANWithoutCheckDigit.length() - 12,PANWithoutCheckDigit.length()) : String.format("%12s", PANWithoutCheckDigit).replace(' ', '0'));// 十六进制转byte数组byte[] PINFieldByteArray = hexString2ByteArr(PINField);// 十六进制转byte数组byte[] PANFieldByteArray = hexString2ByteArr(PANField);// 异或byte[] PINBlockByteArray = new byte[8];for (int i = 0; i < 8; i++) {PINBlockByteArray[i] = (byte) (PINFieldByteArray[i] ^ PANFieldByteArray[i]);}// 返回十六进制return byteArr2HexString(PINBlockByteArray).toUpperCase();
}

3.2、Format 1 PIN block

用于PAN不可获取的场景,由PIN域 拼接 交易域得到。

交易域:在每次PIN block时应当是唯一的,其来源于交易序列号、时间戳、随机数或其他相似情况,取值范围是0x0(0000) ~ 0xF(1111)。

PIN block上送时,交易域不必上送,因为PIN的长度已经知道了。

  • PIN block 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1位(1~4bit):固定值0x1(0001)
  • 第2位(5~8bit):PIN长度,取值范围0x4(0100) ~ 0xC(1100)
  • 第3~16位(9~64bit):PIN,不足14位右补交易域。

以密码123456为例,交易域使用随机数:

代码示例:

/*** Format 1 PIN block* * @param PIN 密码* @return Format 1 PIN block 十六进制字符串*/
private static String format1(String PIN) {// PIN block,64bit,16位十六进制数字// 固定值0x1 + PIN长度 + PIN,不足14位右补交易域String PINBlock = "1" + Integer.toHexString(PIN.length()) + PIN;// 交易域使用随机数,取值范围是0x0~0xFRandom r = new Random();for (int i = 0; i < 14 - PIN.length(); i++) {PINBlock += Integer.toHexString(r.nextInt(16));}return PINBlock.toUpperCase();
}

3.3、Format 2 PIN block

指定IC卡使用,只能用于离线环境,不能用于线上PIN验证。

  • PIN域 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1位(1~4bit):固定值0x2(0010)
  • 第2位(5~8bit):PIN长度,取值范围0x4(0100) ~ 0xC(1100)
  • 第3~16位(9~64bit):PIN,不足14位右补0xF(1111),因为PIN最多12位,所以最后2位一定是0xFF(1111,1111)

以密码123456为例:

代码示例:

/*** Format 2 PIN block* * @param PIN 密码* @return Format 2 PIN block 十六进制字符串*/
private static String format2(String PIN) {// PIN block,64bit,16位十六进制数字// 固定值0x2 + PIN长度 + PIN(不足14位右补F)return "2"+ Integer.toHexString(PIN.length())+ String.format("%-14s", PIN).replace(' ', 'F');
}

3.3、Format 3 PIN block

PIN域PAN域 异或 得到。

  • PIN域 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1位(1~4bit):固定值0x3(0011)
  • 第2位(5~8bit):PIN长度,取值范围0x4(0100) ~ 0xC(1100)
  • 第3~16位(9~64bit):PIN,不足14位右补0xA(1010) ~ 0xF(1111)中随机的或顺序的数字
  • PAN域 共64bit,每4bit为1位十六进制数字,共16位十六进制数字。
  • 第1~4位(1~16bit):固定值0x0000(0000,0000,0000,0000)
  • 第5~16位(17~64bit):PAN,去掉最右边1位校验数字后,从右边数12位,不足12位左补0x0(0000)

以银行卡号6225760008219524,密码123456为例:

代码示例:

/*** Format 3 PIN block* * @param PIN 密码* @param PAN 账号* @return Format 3 PIN block 十六进制字符串*/
private static String format3(String PIN, String PAN) {// PIN域,64bit,16位十六进制数字// 固定值0x3 + PIN长度 + PIN(不足14位右补随机数)String PINField = "3" + Integer.toHexString(PIN.length()) + PIN;// 随机数取值范围0xA~0xFRandom r = new Random();for (int i = 0; i < 14 - PIN.length(); i++) {PINField += Integer.toHexString(r.nextInt(6) + 10);}// PAN域,64bit,16位十六进制数字// 固定值0x0000 + PAN,去掉校验数字,从右边数12位,不足12位左补0x0String PANWithoutCheckDigit = PAN.substring(0, PAN.length() - 1);String PANField = "0000"+ (PANWithoutCheckDigit.length() > 12 ? PANWithoutCheckDigit.substring(PANWithoutCheckDigit.length() - 12,PANWithoutCheckDigit.length()) : String.format("%12s", PANWithoutCheckDigit).replace(' ', '0'));// 十六进制转byte数组byte[] PINFieldByteArray = hexString2ByteArr(PINField);// 十六进制转byte数组byte[] PANFieldByteArray = hexString2ByteArr(PANField);// 异或byte[] PINBlockByteArray = new byte[8];for (int i = 0; i < 8; i++) {PINBlockByteArray[i] = (byte) (PINFieldByteArray[i] ^ PANFieldByteArray[i]);}// 返回十六进制return byteArr2HexString(PINBlockByteArray).toUpperCase();
}

3.4、Format 4 PIN block

  • PIN域128bit,每4bit为1位十六进制数字,共32位十六进制数字。
  • 第1位(1~4bit):固定值0x4(0100)
  • 第2位(5~8bit):PIN长度,取值范围0x4(0100) ~ 0xC(1100)
  • 第3~16位(9~64bit):PIN,不足14位右补0xA(1010)
  • 第17~32位(65~128bit):随机数字,取值范围0x0(0000) ~ 0xF(1111)
  • PAN域 共128bit,每4bit为1位十六进制数字,共32位十六进制数字。
  • 第1位(1~4bit):PAN长度减12,因为PAN最大19位,所以取值范围0x0(0000) ~ 0x7(0111)PAN长度小于12时,取值0x0(0000)
  • 第2~32位(5~128bit):PAN,不足12位左补0x0(0000),超过12位不足20位右补0x0(0000)

以银行卡号6225760008219524,密码123456为例:

Format 4 与0/1/2/3不同,不是先得到PIN block再加密,而是将 PIN域PAN域放到加密过程中,最终得到加密的PIN block。

加密过程:

  • 使用密钥K对PIN域加密,得到结果A;
  • 结果A与PAN域做异或,得到结果B;
  • 使用密钥K对结果B加密,得到加密的PIN block。
  • 解密过程(加密过程的逆过程)
  • 使用密钥K对加密的PIN block解密,得到结果B;
  • 结果B与PAN域做异或,得到结果A;
  • 使用密钥K对结果A解密,得到PIN域。

因Format 4 PIN block涉及密钥加解密过程,此处不提供代码示例,PIN域、PAN域、异或,可参照其他格式PIN block代码示例。

4、ANSI X9.8 Format

ANSI - American National Standards Institute,美国国家标准学会

ANS - American National Standards,美国国家标准

ANS X9.8是在ISO 9564-1标准的基础上增加几处笔记形成的,内容可以认为是一致的。

ANS X9.8中指出PIN block只有Format 0和3建议在此标准下使用,Format 3应当在多次PIN加密都使用相同的PIN加密密钥时使用。

ANSI X9.8 个人密码加密标准。

ANSI X3.92 数据加密标准 (DES)

ANSI X9.9 金融机构信息验证标准。

5、Q/CUP 006.4

中国银联股份有限公司企业标准,Q表示企业,CUP表示中国银联(China UnionPay)

Q/CUP 006.4中规定了PIN block使用ANSI X9.8 Format(带主账号信息),通过标准比对,可以确定就是ANS X9.8中的Format 0,也就是ISO 9564-1中的Format 0。

但是,笔者未查找到ANSI X9.8 Format(不带主账号信息)的定义。不过,从2016年4月生效版的《中国银联银行卡交换系统技术规范》中,可以确定ANSI X9.8 Format(不带主账号信息)的PIN block的生成方式与ANSI X9.8 Format(带主账号信息)中PIN域的生成方式一致,因此,笔者有理由猜测银联标准定义的ANSI X9.8 Format(不带主账号信息)就是ANSI X9.8 Format(带主账号信息)的简化,但是无法猜测其应用场景,对此有了解的朋友可留言告知。

同时,银联标准也定义了互联网支付密码的PIN block计算方式。 1. 互联网支付密码的长度必须在6到20个字符以内; 2. 互联网支付密码均为ASCII码字符,既可以为字符,也可以为数字,或其他符号; 3. PIN block 共24个字节,每个字节使用2位十六进制数字表示,共48位十六进制数字; 前2个字节,互联网支付密码的长度; 剩余22个字节,PIN,6~20位字符,每个字符占1个字节,不足右补0xFF。

以互联网支付密码Hello!123为例:

PIN长度为9,2个字节表示是09,ASCII码是48和57,转为十六进制是0x30和0x39,因此可以得到PIN block为:303948656C6C6F21313233FFFFFFFFFFFFFFFFFFFFFFFFFF

代码示例:

/*** 银联定义互联网支付密码PIN block* * @param PIN 密码* @return PIN block 十六进制字符串*/
private static String formatQCUP(String PIN) {StringBuilder PINBlock = new StringBuilder();// 支付密码长度String PINLength = String.format("%2s", Integer.toHexString(PIN.length())).replace(' ', '0');char[] PINLengthArray = PINLength.toCharArray();for (int i = 0; i < PINLengthArray.length; i++) {PINBlock.append(Integer.toHexString((int) PINLengthArray[i]));}// 密码char[] PINArray = PIN.toCharArray();for (int i = 0; i < PINArray.length; i++) {PINBlock.append(Integer.toHexString((int) PINArray[i]));}// 补0xFFfor (int i = 0; i < 22 - PINArray.length; i++) {PINBlock.append("FF");}return PINBlock.toString().toUpperCase();
}

6、不安全的PIN

ISO 9564-1标准建议客户在设置或更换密码时遵循以下原则:

  1. 不包括客户信息,比如:姓氏、手机号码、生日等;
  2. 不包括账号中连续的数字;
  3. 不包括三个及以上的相同数字;
  4. 不包括三个及以上递增或递减的连续数字;
  5. 不包括历史上重要的日期。

除了这些,笔者从自身项目经验中总结出以下几点供大家参考(主要针对6位数字的密码):

  1. 两个及以上的相同数字;
  2. AABBCC格式,比如:112233
  3. AAABBB格式,比如:111222
  4. AAAABB格式,比如:111122
  5. AAAAAB格式,比如:111112
  6. AAAAAA格式,比如:111111
  7. 两个及以上递增或递减的连续数字;
  8. ABABAB格式,比如:121212、212121
  9. ABCABC格式,比如:123123、321321
  10. ABCDAB格式,比如:123412、432121
  11. ABCDEA格式,比如:123451、543211
  12. ABCDEF格式,比如:123456、654321
  13. 账号中任意连续的6个数字;
  14. 身份证号中任意连续的6个数字;
  15. 手机号中任意连续的6个数字;
  16. 不与之前设置密码相同;
  17. 建立弱密码表,位于弱密码表中的都不安全。

互联网支付密码一般会建议:包含大写字母、小写字母、数字、特殊符号中三种或三种以上的不小于8位的支付密码。

7、彩虹表

简单来说,彩虹表就是密码的合集,你的密码在人家的彩虹表里,就容易被破解;彩虹表很大,大到你的密码很容易出现在其中,但是彩虹表又很小,掌握了彩虹表的原理,你的密码就可以消失的无影无踪。

彩虹表如果展开内容较多,后续会开辟新篇专题交流。本篇主要从以下几点来探讨彩虹表破解的防范措施

存储密码明文是大忌

前几年,存储密码明文的事件被多次曝光,不断刷新着IT从业人员的安全意识下限,好在经过多年的网络安全普及与国家对相关行业软件系统的严格监管,至少笔者所在的金融软件行业领域,存储密码明文的系统已经被淘汰在历史的洪流中了。

公开的哈希算法不安全

彩虹表正是针对公开的哈希算法的破解之法,尽管哈希算法是不可逆的,但是破解它其实更加简单,随着科技的发展,穷举的速度越来越快,有了彩虹表的加持,更加势如破竹。

哈希算法,越来越沦为完整性校验的工具。

为哈希算法加盐是个好主意

没错,我为自己带盐。给密码加盐后再进行哈希,即使被破解,也是加盐的密码,原始密码也是相对安全的。PIN block也可以算作一种加盐方法,只不过PIN block的盐包含在账号中,在不知道账号的前提下,得到了PIN block确实很难破解出密码。

足够聪明可以自定义加密算法

使用自定义的加密算法,彩虹表就失去了用武之地,在加密算法和密钥不泄露的前提下,破解基本是不可能的。但是,世界上聪明人那么多,切忌自以为是,须知人外有人,要时刻保持警惕。

谨防数据库泄露

如果数据库中密码数据泄露,聪明的黑客总能探索到破解之法,因此对数据库要做足够的安全防护。

如果可能

  1. 密码加密算法不可逆,算法不公开,限定于仅核心开发人员(A)知晓;
  2. 数据库加密防护,脱离数据库环境后无法打开,打开方式限定于仅核心运维人员(B)知晓;
  3. 网络防护,限定IP访问,使用堡垒机等手段,访问权限限定于仅核心运维人员(C)拥有;
  4. 以上,凑齐ABC才可能发生数据库泄露,此时发生撞库的概率就变的极低。

当然,如果代码中存在某个bug,也可能被高明的黑客利用,所谓道高一尺,魔高一丈,信息安全的攻防战没有绝对的赢家。

其他建议

  1. 使用密码控件,研发较困难,采购最直接;
  2. 不常登录地区/终端,进行短信验证码校验;
  3. 限制短信验证码失效时间;
  4. 限制短信验证码发送频率;
  5. 密码输入错误2次,进行图形验证码校验;
  6. 密码输入错误5次,锁定账号,并发短信通知客户。

PIN、PAN、PIN block说明相关推荐

  1. 启明云端分享|ESP8089 pin to pin 替代RTL8189,供应稳定、性价比高!

    ESP8089 功能框图 ESP8089 是一个完整且自成体系的WIFI网络解决方案,能够 搭载软件应用,在配合另一个应用处理器实现所有的WIFI网络的功能时,减轻了另一个处理器的压力. ESP808 ...

  2. via/route blockage/size blockage/wire/pin guide/pin blockage/partition

    1.via 中文名称互连线通孔.我们知道,芯片的连线有不同层的金属互连线相互连接.而Via的作用就是连接这些不同层的金属.如下图所示: 一个完整的通孔是由三层组成的,包括两个互连层和一个cut层,cu ...

  3. 睿普康 以太网接口PHY芯片主要替换瑞昱的pin对pin芯片

    睿普康 以太网接口PHY芯片主要替换瑞昱的pin对pin芯片 其他完整学习资料和规格书都在我的附件里,希望大家可以相互学习,有错误方面还请大家正,提供的这些关于PHY的资料也是为了让大家更好的去认识, ...

  4. 国产LIN收发器芯片SIT1028,PIN to PIN替代TJA1028

    概述     SIT1028 是一款内部集成高压 LDO 可应用于 LIN 协议控制器和物理总线之间的接口芯片,可应 用于卡车.公交.小汽车和工业控制等领域,传输速率高达 20kbps.SIT1028 ...

  5. AD原理图编译错误:Details Duplicate pins in component Pin ×× and Pin ××

    问题:在画原理图时候,对原理图文件进行编译会报如下错误:Details Duplicate pins in component Pin ×× and Pin ××. 解决方法:这是因为原理图库中的模型 ...

  6. 完全替代ALTERA EP4CE10, 国产AGM FPGA 的AG10K系列与之pin to pin 兼容

    AGM FPGA与ALTERA Cyclone 4 系列FPGA pin to pin兼容. AG10K与EP4CE10是完全兼容的,软件移植的非常简单,有技术问题,欢迎一起交流探讨. AG10K F ...

  7. 西安航天民芯电子 推出原厂原装MT36291 SOT23-6 PIN对PIN兼替FP6291LR-G1 MT3608

    西安航天民芯电子 推出原厂原装MT36291 SOT23-6 PIN对PIN兼替FP6291LR-G1 MT3608等 品牌:西安航天民芯 型号规格:MT36291 SOT23-6封装 参数描述:电流 ...

  8. 国产最高性价比音频功率放大器LTK8002D,单通道3W/4.2W(PIN对PIN替换)LN4871/SGM4871/HM8002/HAA8002/AD8002

    国产最高性价比音频功率放大器LTK8002D,单通道3W/4.2W(PIN对PIN替换)LN4871/SGM4871/HM8002/HAA8002/AD8002 LTK8002D 是一款高耐压4.2W ...

  9. CN3905规格书|CN3905完全替代MT3905|pin to pin替代MT3905芯片

    CN3905是一款低EMI.异步.降压.开关模式转换器,带有内部功率MOSFET. 它提供了一个非常紧凑的解决方案,在广泛的输入电源范围内提供3.5A的连续电流,具有出色的负载和线路调节.CN3905 ...

  10. GXHT30温湿度传感器——与SHT30 pin to pin 兼容的温湿度传感器

    GXHT30温湿度传感器--与SHT30 pin to pin 兼容的温湿度传感器 文章目录 目录 GXHT30温湿度传感器--与SHT30 pin to pin 兼容的温湿度传感器 文章目录 前言 ...

最新文章

  1. ASP.NET常用函数
  2. 一文总结Datawhale系列分享
  3. Matlab ANN人工神经网络 validation checks
  4. no.4 数据和C 07
  5. VTK:图像高斯平滑用法实战
  6. 充分条件反过来是必要条件吗_“充分必要条件”引发的现实思考
  7. 录播图的分页使用进度条形式显示
  8. 二月春风似剪刀的上一句是什么,二月春风似剪刀全诗赏析
  9. C语言基础学习教程基本语法
  10. linux删除文件、文件夹操作
  11. 最新迅雷“应版权方要求,文件无法下载”的解决办法
  12. java 英语_Java常用英语汇总(更新升级版)
  13. FLUKE754连接电脑hart协议操作指南
  14. 【花雕体验】19 合宙ESP32_C3点亮WS2812B硬屏
  15. shel ---条件、循环
  16. 微信小程序关键字搜索
  17. win10解决redis桌面管理工具RedisDesktopManager右边黑屏问题
  18. [笔试] 搜狗校招哈尔滨,武汉站 - 实现加减乘操作
  19. JAVA强制类型转换常见错误
  20. COM组件开发(四)——VC++调用COM组件的方法

热门文章

  1. 大众点评坐标抓取php,如何抓取(采集)大众点评网的坐标(经纬度)信息
  2. pyecharts制作中国地图
  3. DOM基本操作(获取元素、节点的创建和添加、节点的替换和删除)
  4. 安装报错:TypeError: _classify_installed_files() got an unexpected keyword argument ‘cmake_install_dir‘
  5. 汽车ISP的“去留”之谜
  6. 大四java实习生的一些经历
  7. matlab平坦衰落,平坦衰落信道的MATLAB仿真
  8. Java 随手写的一个英语单词练习器
  9. 前端进击的巨人(三):从作用域走进闭包
  10. win7有线无线可以联网,但是显示图标打红叉