我编写了一个简单的Javacard,用于使用ALG_DES_MAC8_NOPAD签名计算输入数据的签名,如下所示:
package testPrj ;
import javacard.framework.*;
import javacard.security.*;
public class testPrj extends Applet
{
private Signature sig8;
private DESKey key8;
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new testPrj();
}
public testPrj(){
sig8 = Signature.getInstance(Signature.ALG_DES_MAC8_NOPAD, false);
key8 = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES, false);
register();
}
public void process(APDU apdu)
{
if (selectingApplet())
return;
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS])
{
case (byte)0x00:
apdu.setIncomingAndReceive();
key8.setKey(buf, ISO7816.OFFSET_CDATA);
sig8.init(key8, Signature.MODE_SIGN, buf, (short)(ISO7816.OFFSET_CDATA + 8), (short)8);
sig8.sign(buf, (short)(ISO7816.OFFSET_CDATA + 16), (short)8, buf, (short)0);
apdu.setOutgoingAndSend((short)0, (short)8);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}正如您在上面看到的,这个applet只支持一个APDU命令。这个命令的前8个字节是DES键,第二个8个字节是IV,最后8个字节是我们想要计算它的签名的输入数据。
现在,我们可以使用Key = 11 11 11 11 11 11 11 11和IV = 22 22 22 22 22 22 22 22计算11 11 11 11 11 11 11 11的签名,如下所示:
// Select Applet
Send: 00 A4 04 00 06 <Applet AID> 00
Recv: 90 00
// Request DES Signature
Send: 00 00 00 00 18 11 11 11 11 11 11 11 11 22 22 22 22 22 22 22 22 33 33 33 33 33 33 33 33
Recv: F4 03 79 AB 9E 0E C5 33 90 00 <== DES Signature + Status Words好的,现在看一看这张图片(来自在线工具):

正如您可能注意到的,输出与applet的响应相等。
因此,在CBC模式下,DES_MAC8签名与DES加密是等价的。
现在来看一下RFC中关于DES的定义:
6.4.6.DES密码-块链式校验和(Des) DES校验和的计算方法是在明文前加上一个8八进制混合器,对结果执行DES模式加密,使用密钥和初始化向量为零,取密文的最后一个块,在相同的混淆器前加上相同的混淆器,并使用密钥的一个变体来加密使用DES模式的配对,其中该变量是通过使用常量F0F0F0F0F0F0F0F0对密钥进行排他性排序来计算的。初始化向量应为零。由此产生的校验和是128位(16倍)长,其中64位是冗余的。这个校验和是防篡改和防撞的.
显然,这个定义与applet/online工具中发生的情况不同。所以:
队列:DES与DES签名不同吗?它们有不同的用途吗?换句话说,DES-MAC是否证明了DES签名不能证明(反之亦然)呢?。
发布于 2020-08-30 20:03:59
原因很简单,您引用的DES是特定于Kerberos 5。这不是一个CBC-MAC,虽然它似乎使用相同的CBC模式.
https://stackoverflow.com/questions/63660819
复制相似问题