笔者目前使用的jdk版本是1.6.0_29,Eclipse版本是Juno Release,Build id 20120614-1722。加密机使用卫士通SJL05型号金融数据加密机。如无特殊说明,本文所有的Java代码都是基于此。
лист регистраций изменений
| номер версии | Дата проверки | Примечания к редакции |
|---|---|---|
| V0.1 | 2018/09/28 | первый черновик |
| V1.0 | 2018/10/12 | выпускать |
использованная литература
- Q/CUP 006.4-2015 Стандарт предприятия China UnionPay Co., Ltd. Техническая спецификация для системы обмена банковскими картами China UnionPay (международный том), часть 4 Спецификация управления передачей безопасности данных
- Руководство программиста машины для шифрования финансовых данных типа SJL05
Система ключей UnionPay
Согласован ключ между системой обмена информацией о банковских картах China UnionPay (CUPS) и каждым учреждением доступа к сети, который состоит из трех уровней:
Слой 1: МК
Мастер-ключ, мастер-ключ. Ключ верхнего уровня шифровальной машины, который вводится и генерируется вручную, состоит из трех частей, которыми соответственно управляют три человека, которые хранятся в шифровальной машине и защищаются аппаратным оборудованием шифровальной машины.
Уровень 2: ММК
Мастер-ключ участника, мастер-ключ участника. Это относится к ключу шифрования ключа, назначенному учреждениям-членам в системе безопасности банковских карт, который используется для шифрования ключа следующего уровня и защищен шифрованием с помощью главного ключа (MK). CUPS и агентство доступа к сети генерируют по половине, которые синтезируются в аппаратном оборудовании; или CUPS случайным образом генерирует и хеширует два компонента в шифровальной машине; или метод генерации ключа согласовывается обеими сторонами.
Третий слой: ПИК, МАК
- PIN-ключ, ключ, используемый для шифрования PIN-кода.
- Ключ MAC, ключ, используемый для генерации данных проверки достоверности (MAC) сообщения транзакции.
В совокупности именуемый ключом данных, ключ данных зашифрован и защищен мастер-ключом участника (MMK). Генерируется генератором случайных чисел в машине аппаратного шифрования. Шифровальная машина CUPS генерирует ключ данных, а агентство доступа к сети получает и сохраняет ключ данных, отправленный CUPS. Когда CUPS сочтет это необходимым, он может активно отправить сообщение сброса ключа в агентство доступа к сети. Когда агентству доступа к сети требуется новый ключ, оно должно отправить сообщение в CUPS для повторного ввода ключа.
HSM
Аппаратно-защитный модуль, аппаратная шифровальная машина, периферийное аппаратное устройство, шифрующее передаваемые данные, используемое для шифрования и расшифровки ПИН-кода, проверки правильности источника сообщений и файлов, хранения ключей.
Как следует из названия, шифровальная машина — это машина, преимущества которой заключаются в безопасности аппаратного устройства для хранения ключей и эффективности операций шифрования и дешифрования.
Изображение взято с официального сайта Weishitong,Внедрение продукта машины для шифрования финансовых данных.
Исключая сценарии, в которых промышленность требует использования шифровальной машины, вы можете решить, следует ли использовать шифровальную машину в соответствии с реальной ситуацией.Использование шифровальной машины не всегда хорошо.
Уэстон
Компания Westone Information Industry Co., Ltd. была основана в 1998 году по инициативе 30-го научно-исследовательского института Китайской корпорации электронных технологий. Опираясь на 40-летнее накопление глубоких профессиональных технологий и человеческих ресурсов в 30 учреждениях, с эффективным современным механизмом работы предприятия и непрерывными стратегическими инновациями, Westone превратилась в самого доминирующего лидера отрасли информационной безопасности в моей стране, и основываясь на этом как на ядре для расширить налоговые поступления Электронные, финансовые электронные, электронной коммерции и других безопасных ИТ-бизнеса для достижения крупномасштабного развития предприятий. И он был успешно зарегистрирован в июле 2008 года, став «первой акцией информационной безопасности Китая».
Компания, в которой я работаю, использует шифровальные машины, приобретенные у Westone, и автор никогда не связывался с другими марками шифровальных машин, поэтому остальная часть этой статьи касается только шифровальных машин Westone и модели SJL05, потому что документы шифровальной машины модели SJL05 могут могут быть легко получены из Интернета.Существует проблема утечки.Что касается использования других моделей или других марок шифровальных машин,после понимания принципов,в целом то же самое,и нетрудно сделать выводы из одного случая.
SJL05
Обратитесь к «Руководству программиста машины для шифрования финансовых данных SJL05», хотя определение системы ключей в машине шифрования SJL05 четко не определено, все же можно сделать вывод о трехуровневой структуре, которая соответствует спецификации системы ключей UnionPay в соответствии с интерфейс:
Слой 1: ЛМК
Local Master Key, локальный мастер-ключ. Аналогичен МК в ключевой системе UnionPay.
Уровень 2: ЗМК/БМК, ТМК/АТК
- ZMK, Zone Master Key, мастер-ключ зоны.
- TMK, Мастер-ключ терминала, Мастер-ключ терминала.
Аналогичен MMK в ключевой системе UnionPay.
Третий слой: ЗАК, ЗПК, ТАК, ТПК
- ZAK, ключ аутентификации зоны, ключ аутентификации зоны.
- ZPK, ПИН-ключ зоны, ПИН-ключ зоны.
- TAK, административный ключ терминала, ключ аутентификации терминала.
- ТПК, Терминальный ПИН-ключ шифрования, Терминальный ПИН-ключ.
ZAK и TAK эквивалентны MAK в системе ключей UnionPay, ZPK и TPK эквивалентны PIK в системе ключей UnionPay.
В некоторых сценариях применения также может быть получена более сложная система ключей, такая как 4-уровневая структура:
Однако независимо от того, какая это система ключей, открытый текст ключа не будет раскрыт, ключ верхнего уровня защищает ключ нижнего уровня, и принцип, согласно которому ключ верхнего уровня защищен аппаратным обеспечением шифровальной машины остается неизменной.
Практическое применение шифровальной машины
В этой главе описывается, как вызвать конкретный интерфейс шифровальной машины SJL05 в бизнес-сценарии POS-терминала. Логика вызова каждого финучреждения разная.Автор предлагает только базовую идею.При практическом применении каждый должен адаптироваться к местным условиям и избегать подражания.Если есть какие-то неуместности прошу критиковать и исправлять.
Во-первых, взгляните на базовую схему потока данных, которая на самом деле может быть более сложной.
- POS-терминал обозначен буквой P
- Приобретатель обозначается буквой A
- Трансферное агентство представлено B
- Эмитент карты обозначается буквой C
Ключевая система POS-терминала:
Система ключей эквайера:
Ключевая система трансфер-агентства:
Система ключей эмитента:
Список интерфейсов, задействованных в шифровальных машинах
Во всем процессе транзакции автор предлагает логику вызова интерфейса шифровальной машины модели SJL05, которая включает следующие интерфейсы.
| код команды | имя | иллюстрировать |
|---|---|---|
| 0X08 | Сгенерируйте и сохраните мастер-ключ указанной длины и распечатайте открытый текст в криптографическом конверте. | Сгенерируйте главный ключ зоны, или главный ключ терминала, или локальный главный ключ указанной длины, сохраните его в указанном месте шифровальной машины и распечатайте открытый текстовый ключ на зашифрованном конверте через последовательный принтер, если тип ключа — главный ключ зоны. key Или мастер-ключ терминала, который также вернет зашифрованный текст, зашифрованный с помощью LMK. |
| 0XD108 | зашифрованный открытый текстовый ключ | Введите открытый текстовый ключ указанной длины, зашифруйте его с помощью локального главного ключа шифровальной машины и верните его зашифрованный текстовый ключ и проверочный код. |
| 0X0510 | Зашифровать главный ключ терминала с помощью локального главного ключа | Введите открытый текст TMK, зашифруйте его с помощью локального главного ключа, выведите его и сохраните в хост-системе. |
| 0X0512 | Сгенерировать ключи данных терминала (зашифрованные с помощью TMK и LMK) | Шифровальная машина генерирует ключ данных, который шифруется главным ключом терминала TMK и локальным главным ключом (LMK) соответственно, а затем выводится. |
| 0X0410 | Запрос на создание MAC (MAK переменной длины) | запрос на генерацию MAC |
| 0X0411 | Запрос на проверку MAC (MAK переменной длины) | Запрос на проверку MAC |
| 0X0402 | Преобразование PINBLOCK (произвольная длина PIK) | Преобразование ПИН-БЛОКА |
| 0X76 | Используйте входной ключ для шифрования/дешифрования данных, а затем выполните операцию MD5 с данными. | Используйте входной 16-байтовый ключ для шифрования или дешифрования данных с помощью CBC или ECB 3DES/DES и, наконец, выполните операцию дайджеста MD5 для результатов шифрования и дешифрования. |
ключевая инициализация
-
转接机构Инициализировать локальный главный ключB_LMK(0X08), сгенерированный и переданный收单机构региональный мастер-ключAB_ZMK(0X08), сгенерированный и переданный发卡机构региональный мастер-ключBC_ZMK(0X08). существует转接机构В шифровальной машине,B_LMKОткрытый текст защищен оборудованием шифрования машины,AB_ZMK,BC_ZMKЗависит отB_LMKзащита шифрования; -
收单机构Инициализировать локальный главный ключA_LMK(0X08), ввод转接机构Распределенный региональный мастер-ключAB_ZMK(0XD108), введите иPOS终端Согласованный мастер-ключ терминалаPA_TMK(0X0510).收单机构В шифровальной машине,A_LMKОткрытый текст защищен аппаратным обеспечением шифровальной машины,AB_ZMK,PA_TMKЗависит отA_LMKзащита шифрования; -
发卡机构Инициализировать локальный главный ключC_LMK(0X08), ввод转接机构Распределенный региональный мастер-ключBC_ZMK(0XD108).发卡机构В шифровальной машине,C_LMKОткрытый текст защищен аппаратным обеспечением шифровальной машины,BC_ZMKЗависит отC_LMKзащита шифрования; -
POS终端Введите мастер-ключ терминалаPA_TMK,PA_TMKоткрытый текстPOS终端Защита модуля безопасности.
войти
-
收单机构К转接机构Ключи данных запроса, в том числе: ключи аутентификации областиAB_ZAK, PIN-код областиAB_ZPK. существует收单机构а также转接机构В шифровальной машине,AB_ZAK,AB_ZPKпо мастер-ключу зоныAB_ZMKЗащищать; -
发卡机构К转接机构Ключи данных запроса, в том числе: ключи аутентификации областиBC_ZAK, региональный PIN-кодBC_ZPK. существует发卡机构а также转接机构В шифровальной машине,BC_ZAK,BC_ZPKпо мастер-ключу зоныBC_ZMKЗащищать; -
POS终端К收单机构Ключ данных запроса (0x0512), содержащий: ключ аутентификации терминалаPA_TAK, ПИН-ключ терминалаPA_TPK. существуетPOS终端модуль безопасности и收单机构В шифровальной машине,PA_TAK,PA_TPKпо мастер-ключу терминалаPA_TMKЗащищать.
запрос транзакции
-
POS终端проведите, используйтеPA_TPKПароль шифрования (блок PIN),PA_TAKСгенерируйте MAC-адрес сообщения о транзакции и отправьте сообщение о транзакции на收单机构; -
收单机构Проверьте MAC (0X0411), используйтеAB_ZPKПересылка зашифрованного блока PIN (0X0402),AB_ZAKСгенерируйте MAC-адрес сообщения о транзакции (0X0410) и отправьте сообщение о транзакции на转接机构; процесс шифрованияPA_TMK расшифровывает PA_ZPK, PA_ZPK расшифровывает PIN-блок, AB_ZMK расшифровывает AB_ZPK, AB_ZPK шифрует PIN-блок; -
转接机构Проверьте MAC (0X0411), используйтеBC_ZPKПередача блока PIN-кода шифрования (0X0402),BC_ZAKСгенерируйте MAC-адрес сообщения о транзакции (0X0410) и отправьте сообщение о транзакции на发卡机构; процесс шифрованияAB_ZMK расшифровывает AB_ZPK, AB_ZPK расшифровывает PIN-блок, BC_ZMK расшифровывает BC_ZPK, BC_ZPK шифрует PIN-блок; -
发卡机构Проверьте MAC (0X0411), используйтеBC_ZPKПередайте зашифрованный блок PIN (0X76), чтобы проверить хеш-значение блока PIN; - После завершения транзакции вернитесь на исходный путь, процесс шифрования передачиBC_ZMK расшифровывает BC_ZPK, BC_ZPK расшифровывает PIN-блок, а PIN-блок вычисляет хеш-значение..
Возьмите интерфейс в качестве примера для написания кода.
формат сообщения
| поле ввода | длина | Типы | Примечание |
|---|---|---|---|
| Заказ | 1 | H | 0x76 |
| Индексный номер банка | 2 | H | порядковый номер главного ключа зоны |
| длина ключа | 1 | H | 0x08 ; 0x10 |
| КЛЮЧ | 16 | H | Ключ для добавления/расшифровки данных (шифрование zmk) |
| начальный вектор | 8 | H | Начальный вектор для шифрования CBC |
| Зашифровать/расшифровать идентификатор | 1 | H | 1 для шифрования, 0 для расшифровки |
| Идентификатор алгоритма | 1 | H | Бит 0: ECB=0, CBC=1 Бит 1: 3DES=0, DES=1 |
| LEN | 2 | H | Длина обрабатываемых данных |
| данные | N | H | N=ДЛСТР |
| поле вывода | длина | Типы | Примечание |
|---|---|---|---|
| код ответа | 1 | A | "А" |
| Сводные данные | 16 | H | |
| или | |||
| код ответа | 1 | A | "Э" |
| код ошибки | 1 | H | 0x0C: недопустимый номер индекса основного ключа банка 0x59: неправильная длина входных данных 0x2C: неверный мастер-ключ банка 0x10: неверный режим алгоритма |
Процесс обработки SJL05
- Вынуть мастер-ключ указанной зоны ZMK;
- Используйте ZMK для выполнения расшифровки 3DES для входного ключа KEY, чтобы получить открытый текст ключа PKEY;
- Проверяем, кратна ли длина входных данных 8, если нет, заполняем 0x00, чтобы длина была кратна 8;
- В соответствии с идентификатором шифрования/дешифрования и идентификатором алгоритма используйте PKEY для шифрования или дешифрования ДАННЫХ с помощью CBC/ECB 3DES/DES;
- Суммарные операции MD5 для зашифрованных или расшифрованных результатов;
- В случае успеха вернуть 16-байтовый итоговый результат MD5.
пример кода
Создайте родительский класс команды машины шифрования
package com.godson.util.hsm;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 加密机命令父类
*/
abstract public class HSMCommand {
// 错误码
protected int errorCode;
// 封装消息报文
abstract public void packetInputField(OutputStream os) throws Exception;
// 解析响应报文
public boolean parseOutputField(InputStream is) throws Exception {
// 应答码
int retCode = is.read();
if ('E' == (char) retCode) {
errorCode = is.read();
return false;
}
return true;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}
Наследовать родительский класс и реализовать класс инструкций 0x76.
package com.godson.util.hsm;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* 0X76 用输入密钥对数据加/解密,再对数据进行MD5运算
*
* <pre>
* 利用输入的16字节密钥对数据做3DES/DES的CBC或ECB加密或解密,最后对加解密结果进行MD5摘要运算。
* </pre>
*/
public class Cmd0X76 extends HSMCommand {
private short zmkIndex;
private byte keyLen;
private byte[] key;
private byte[] initVect;
private byte enOrDe;
private byte algorithm;
private short dataLen;
private byte[] data;
private byte[] md;
@Override
public void packetInputField(OutputStream os) throws Exception {
int len = 32 + dataLen;
ByteBuffer buf = ByteBuffer.allocate(len);
buf.put((byte) 0x76); // 命令,0x76
buf.putShort(zmkIndex); // 银行索引号,区域主密钥索引号
buf.put(keyLen); // 密钥长度
buf.put(key); // 加/解数据的密钥(zmk加密)
buf.put(initVect); // CBC加密的初始向量
buf.put(enOrDe); // 加/解密标识,1为加密,0为解密
buf.put(algorithm); // 算法标识,第0位:ECB=0,CBC=1,第1位:3DES=0,DES=1
buf.putShort(this.dataLen); // 处理数据的长度
buf.put(data); // 数据
os.write(buf.array());
}
@Override
public boolean parseOutputField(InputStream is) throws Exception {
if (!super.parseOutputField(is)) {
return false;
}
DataInputStream dis = new DataInputStream(is);
md = new byte[16];
dis.read(md); // 摘要数据
return true;
}
public short getDataLen() {
return dataLen;
}
public void setDataLen(short dataLen) {
this.dataLen = dataLen;
}
public short getZmkIndex() {
return zmkIndex;
}
public void setZmkIndex(short zmkIndex) {
this.zmkIndex = zmkIndex;
}
public byte getKeyLen() {
return keyLen;
}
public void setKeyLen(byte keyLen) {
this.keyLen = keyLen;
}
public byte[] getKey() {
return key;
}
public void setKey(byte[] key) {
this.key = key;
}
public byte[] getInitVect() {
return initVect;
}
public void setInitVect(byte[] initVect) {
this.initVect = initVect;
}
public byte getEnOrDe() {
return enOrDe;
}
public void setEnOrDe(byte enOrDe) {
this.enOrDe = enOrDe;
}
public byte getAlgorithm() {
return algorithm;
}
public void setAlgorithm(byte algorithm) {
this.algorithm = algorithm;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public byte[] getMd() {
return md;
}
public void setMd(byte[] md) {
this.md = md;
}
}
модуль вызова шифровальной машины
package com.godson.util.hsm;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* 加密机模块
*/
public class HSMUtil {
private String host; // 加密机IP地址
private int port; // 加密机端口
public HSMUtil(String host, int port) {
this.host = host;
this.port = port;
}
// 执行加密机指令
public boolean execute(HSMCommand command) throws Exception {
Socket sock = null;
OutputStream os = null;
InputStream is = null;
try {
// 建立Socket连接
sock = new Socket(host, port);
sock.setSoTimeout(5000);
// 封装消息报文,并送给加密机
os = sock.getOutputStream();
command.packetInputField(os);
os.flush();
// 从加密机接受响应报文
is = sock.getInputStream();
return command.parseOutputField(is);
} finally {
// 关闭加密机读写流和连接
try {
if (os != null) {
os.close();
os = null;
}
if (is != null) {
is.close();
is = null;
}
if (sock != null) {
sock.close();
sock = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Метод вызова шифровальной машины здесь несовершенен. Когда параллелизм коротких соединений высок, легко сгенерировать большое количество состояний TIME_WAIT. Причина генерации TIME_WAIT: когда TCP закрывает соединение взмахом руки четыре раза (при условии, что клиент активно закрывает соединение) После отправки ACK клиенту необходимо подождать некоторое время, чтобы убедиться, что сервер успешно получил ACK или не получил ACK и может повторно отправить FIN обычно, чтобы избежать ошибок сервера.
Большинство решений, предлагаемых в Интернете, заключаются в изменении параметров сервера:
Измените /etc/sysctl.conf:
net.ipv4.tcp_syncookies = 1 #Указывает, что файлы cookie SYN включены. Когда очередь ожидания SYN переполняется, включите файлы cookie, чтобы справиться с этим, что может предотвратить небольшое количество атак SYN.Значение по умолчанию равно 0, что означает, что она закрыта.
net.ipv4.tcp_tw_reuse = 1 # Указывает, что повторное использование включено. Разрешить повторное использование сокетов TIME-WAIT для новых TCP-соединений, по умолчанию 0, что означает закрытие
net.ipv4.tcp_tw_recycle = 1 #Указывает, что включена быстрая перезарядка сокетов TIME-WAIT в TCP-соединении.По умолчанию 0, что означает, что он закрыт. > Когда net.ipv4.tcp_timestamps включен, он вступит в силу только тогда, когда включен net.ipv4.tcp_tw_recycle
net.ipv4.tcp_timestamps = 1 #Указывает на включение быстрого перезапуска сокетов TIME-WAIT в соединениях TCP, значение по умолчанию равно 0, что означает закрытие.
net.ipv4.tcp_fin_timeout = 30 # Используется для установки времени пребывания в состоянии FIN_WAIT_2После сохранения выполните команду /sbin/sysctl -p, чтобы изменения вступили в силу.
Я полагаю, что не может легко модифицировать параметры сервера, должны попытаться найти прорыв, чтобы решить проблему из самой программы, вместо короткого до длительного подключения соединение является лучшим способом, но обнаружил, что он не поддерживает длинные подключения к шифрованию Интерфейсный документ, но все же можно использовать объединение соединений и другие программы для уменьшения близкого розетки, оставляя вас подумать о реализации.