为
`BDK = "0123456789ABCDEFFEDCBA9876543210"` `KSN = "FFFF9876543210E00008"` 生成的密文如下
"C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"`我找到了here。我知道这个密文是基于BDK和KSN的,但是这个128个长度的密文是如何生成的呢?它涉及哪些步骤或用于此的算法?有人能用简单的步骤解释一下吗。我发现我在谷歌上搜索时很难理解我得到的文档。
发布于 2013-07-08 01:16:04
关于DUKPT,在上有一些解释。如果这还不能满足你,这里有一些简短的解释。
引用http://www.maravis.com/library/derived-unique-key-per-transaction-dukpt/
什么是DUKPT?
派生的每事务唯一密钥(DUKPT)是一种密钥管理方案。它使用一次性加密密钥,该密钥来自加密的实体(或设备)和解密数据的实体(或设备)共享的秘密主密钥。为什么选择DUKPT?任何加密算法的安全性都取决于它的密钥。如果用于通过算法加密数据的密钥不安全,则最强算法是无用的。这就像用最大最坚固的锁锁住你的门,但如果你把钥匙藏在门垫下面,锁本身就没用了。当我们谈论加密时,我们还需要记住,数据必须在另一端解密。通常,任何加密方案中最薄弱的环节都是在加密方和解密方之间共享密钥。DUKPT是一种尝试,以确保双方都可以加密和解密数据,而不必传递加密/解密密钥。VISA发布的加密最佳实践文档还建议使用DUKPT实现PCI DSS合规性。
DUKPT如何工作
DUKPT使用为每个事务生成的一次性密钥,然后将其丢弃。优点是,如果这些密钥中的一个被泄露,那么只有一个事务会被泄露。使用DUKPT,发起方(例如,Pin Entry设备或PED)和接收方(处理器、网关等)共享密钥。此密钥实际上并不用于加密。取而代之的是,使用从该主密钥派生的另一个一次性密钥来加密和解密数据。重要的是要注意,主密钥不应该从导出的一次性密钥中恢复。要解密数据,接收端必须知道使用了哪个主密钥来生成一次性密钥。这意味着接收端必须存储和跟踪每个设备的主密钥。对于支持许多设备的人来说,这可能是一项繁重的工作。需要一种更好的方法来处理这个问题。这就是它在现实生活中的工作方式:接收器有一个称为基础派生密钥(BDK)的主密钥。BDK应该是秘密的,永远不会与任何人分享。此密钥用于生成称为初始Pin加密密钥(IPEK)的密钥。由此生成一组名为Future keys的密钥,并丢弃IPEK。设备制造商将每个未来密钥嵌入到PED中,并与其共享这些密钥。这个额外的推导步骤意味着接收器不必跟踪进入PED的每个密钥。它们可以在需要时重新生成。

接收器与PED制造商共享未来密钥,PED制造商在每个PED中嵌入一个密钥。如果这些密钥中的一个被泄露,PED可以用从BDK导出的新的未来密钥来更新密钥,因为BDK仍然是安全的。
加密和解密
当数据需要从PED发送到接收器时,该设备中的Future key用于生成一次性密钥,然后将该密钥与加密算法一起使用来加密数据。然后,该数据与密钥序列号(KSN)一起被发送到接收器,密钥序列号(KSN)由设备ID和设备事务计数器组成。

然后,接收器根据KSN生成IPEK,并从中生成设备使用的Future密钥,然后生成用于加密数据的实际密钥。有了这个密钥,接收器将能够解密数据。
Source
发布于 2013-07-08 01:11:17
首先,让我引用你链接的完整源码,其中你只提供了3行……
require 'bundler/setup'
require 'test/unit'
require 'dukpt'
class DUKPT::DecrypterTest < Test::Unit::TestCase
def test_decrypt_track_data
bdk = "0123456789ABCDEFFEDCBA9876543210"
ksn = "FFFF9876543210E00008"
ciphertext = "C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12"
plaintext = "%B5452300551227189^HOGAN/PAUL ^08043210000000725000000?\x00\x00\x00\x00"
decrypter = DUKPT::Decrypter.new(bdk, "cbc")
assert_equal plaintext, decrypter.decrypt(ciphertext, ksn)
end
end现在你要问的是“密文”是怎么产生的.
好吧,首先我们知道它是基于“明文”的,它在代码中用来验证解密是否有效。
明文是0填充的-通过使用此DecrypterTest TestCase验证解密,它适合正在测试的加密。
让我们看一下编码代码,然后...
我在https://github.com/Shopify/dukpt/blob/master/lib/dukpt/encryption.rb找到了相关的加密代码。
由于DecrypterTEst使用"cbc",很明显,加密使用:
@cipher_type_des = "des-cbc"
@cipher_type_tdes = "des-ede-cbc"再往下一点加密代码,下面就解决了我们寻找答案的问题:
ciphertext = des_encrypt(...这表明我们确实在查看DES加密的结果。
现在,DES的块大小为64位。这是(64/8=) 8字节二进制,或者“密文”是字节的十六进制编码文本表示- 16个字符的十六进制。
“密文”长度为128个十六进制字符,这意味着它包含(128个十六进制字符/16个十六进制chars=) 8个DES块,每个64位加密信息。
将所有这些总结为一个简单的答案:
在查看“密文”时,您看到的是(8个块) DES加密数据,它使用人类可读的十六进制(2个十六进制字符=1个字节)表示法,而不是DES加密将产生的原始二进制字节。
至于“重新创建”密文所涉及的步骤,我倾向于告诉您只需使用ruby项目的相关部分,即您提出问题的基础。只需查看源码即可。"“中的文件很好地解释了这一切,我非常确定您需要的所有功能都可以在项目的GitHub存储库中找到。或者,您可以尝试自己重新创建它-使用您选择的首选编程语言。您只需要处理两件事: DES加密/解密和bin- to -hex/hex-to-bin转换。
发布于 2015-06-19 17:30:31
由于这是关于这个的第一个话题,我想我应该分享一下我是如何对密文进行编码的。这是我第一次使用Ruby,特别是为了使用DUKPT
首先,我必须获取ipek和pek (与decrypt中相同)方法。然后解压明文字符串。将解压后的字符串转换为72字节的数组(同样,如果我的术语不正确,请原谅)。
我注意到在dukpt gem作者示例中,他使用了以下纯文本字符串
“%B5452300551227189^霍根/保罗^08043210000000725000000?\x00\x00”
我觉得这个字符串是不正确的,因为名称(AFAIK)后面不应该有空格。所以它应该是
"%B5452300551227189^HOGAN/PAUL^08043210000000725000000?\x00\x00\x00\x00“
总而言之,这是我最终使用的解决方案,它可以加密字符串,然后使用DUKPT解密它
class Encrypt
include DUKPT::Encryption
attr_reader :bdk
def initialize(bdk, mode=nil)
@bdk = bdk
self.cipher_mode = mode.nil? ? 'cbc' : mode
end
def encrypt(plaintext, ksn)
ipek = derive_IPEK(bdk, ksn)
pek = derive_PEK(ipek, ksn)
message = plaintext.unpack("H*").first
message = hex_string_from_unpacked(message, 72)
encrypted_cryptogram = triple_des_encrypt(pek,message).upcase
encrypted_cryptogram
end
def hex_string_from_unpacked val, bytes
val.ljust(bytes * 2, "0")
end结束
"%B5452300551227189^HOGAN/PAUL^08043210000000725000000?“
FFFF9876543210E00008 boomedukpt
(我的ruby gem、KSN和纯文本字符串)
2542353435323330303535313232373138395e484f47414e2f5041554c5e30383034333231303030303030303732353030303030303f000000000000000000000000000000000000
(我的ruby gem在调用hex_string_from_unpacked之后在解包的字符串上做了一个放入操作)
C25C1D1197D31CAA87285D59A892047426D9182EC11353C0B82D407291CED53DA14FB107DC0AAB9974DB6E5943735BFFE7D72062708FB389E65A38C444432A6421B7F7EDD559AF11
(我的ruby gem在加密的字符串上做了一次puts )
%B5452300551227189^HOGAN/PAUL^08043210000000725000000?
(我的ruby gem在dukpt gem上调用decrypt之后做了一次puts )
https://stackoverflow.com/questions/17362567
复制相似问题