Java 实现 3DES 和 DUKPT 以通过键盘模拟解密信用卡 reader 数据?

Java implementation of 3DES and DUKPT for decryption of credit card reader data through keyboard emulation?

我们有一个在线键入界面,并且支持信用卡刷卡功能。在当今的行业中,卡 reader 应该在将信息编码为 ASCII 之前对其进行加密,然后由服务器端进行解密。 (所以本地机器永远看不到卡信息)

我在键盘模拟模式下使用 MagTek 卡 reader,并为了测试目的注入了 ANSI 标准键。一旦解码和解密成功,我们将在 MagTek 上注册我们自己的密钥并订购一些生产用 readers.

我知道此解密之前已在 C# 和其他语言中实现,但需要 Java 中的内容,或者可能包含在 Java webapp 中的其他一些可通过 CLI 访问的程序。我即将继续将一些 C# 代码移植到 Java,但首先需要设置一个 C# 环境。 (我以前从未这样做过。)

一旦我确保 C# 版本运行良好,我就知道我可以使用我常用的调试技术消除移植过程中的任何错误。

在我完成所有这些之前,如果有更简单的方法请告诉我。我认为这已经在 Java 中完成,但也许没有...

部分答案,CW 供任何人添加。

首先,(对我而言)不清楚你是想 运行 在刷卡设备所在的 PC 或类似设备上,可能已下载(如 applet 或 webstart),还是只是获取加密的刷卡数据(在网络表单中?)并将其发送到您的服务器进行解密。我建议后者使 PCI DSS 合规性更容易。

Java crypto 在名称 DESede 下肯定会 3DES(不区分大小写,就像所有 JCA 密码名称一样)。有一点不太明显:SunJCE 中的实现仅处理完整的 24 字节密钥。 DUKPT 使用“2-key 3DES”,因此您需要将 "left" 复制到字节 0-7,将 "right" 复制到 8-15,再将 "left" 复制到 16-23。如果您使用 BouncyCastle(就像我的商店那样),它可以使用 16 字节的密钥并在内部进行复制,这样会稍微方便一些。 (Java 中的对称密钥是精简包装器 class 中的字节数组,通常 javax.crypto.spec.SecretKeySpec。)

如果您一般不熟悉 Java 加密,模式是您从 "provider" 中获得特定算法或模式的 "instance"(您可以指定一个或让 Java 自动选择;几个是内置的,可以添加更多,例如 "bcprov" 来自 www.BouncyCastle.org) 使用通用 API class CipherSignatureMessageDigest 等,然后使用所需的参数(例如键或 IV 和方向)初始化该实例,然后调用方法获取输入数据和 return 输出单独的(可能是多个)步骤或简单的组合 doFinal (适合您的情况)。 JCA 手册 http://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Cipher and javadoc for the applicable API class javax.crypto.Cipher (at http://docs.oracle.com/javase/8/docs/api/index.html 并自动显示在领先的 IDE 中)对此有相当完整的详细信息。

我还没有看到 DUKPT 的任何 open/free 实现,但这并不能证明没有。直接从 X9.24 编写步骤虽然有点乏味,但没有人提供更好的方法。