Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Java)使用三重数据加密算法(TDEA)进行密钥包装,用于已知答案测试(KAT)_Java_Encryption_Key_Des - Fatal编程技术网

(Java)使用三重数据加密算法(TDEA)进行密钥包装,用于已知答案测试(KAT)

(Java)使用三重数据加密算法(TDEA)进行密钥包装,用于已知答案测试(KAT),java,encryption,key,des,Java,Encryption,Key,Des,我正在为密钥包装做一个已知答案测试,我正在寻找正确的算法或实现。 如“官方”测试中所述() 我想使用三重数据加密算法(TDEA),所以我正在使用NIST的官方测试向量 (在此处获取测试向量集:) 在文件“TKW_AE.txt”中,K是密钥,P是要包装的密钥(“明文”),C是加密/包装的密文(“输出”): 我的实现似乎可以工作,因为它将明文(要包装的密钥)打包,并将密文解压缩到原始密钥,但在运行 使用相同的密钥(“K”)和明文(“P”)进行测试,我在密文上得到了不同的结果,这是因为用于算法“DES

我正在为密钥包装做一个已知答案测试,我正在寻找正确的算法或实现。 如“官方”测试中所述() 我想使用三重数据加密算法(TDEA),所以我正在使用NIST的官方测试向量 (在此处获取测试向量集:) 在文件“TKW_AE.txt”中,K是密钥,P是要包装的密钥(“明文”),C是加密/包装的密文(“输出”):

我的实现似乎可以工作,因为它将明文(要包装的密钥)打包,并将密文解压缩到原始密钥,但在运行 使用相同的密钥(“K”)和明文(“P”)进行测试,我在密文上得到了不同的结果,这是因为用于算法“DESedeWrap”的随机IV

我的问题:如何设置包装/展开密码以符合“官方”测试向量结果(在我的示例中,密文(“C”)需要“7A72BBCA3a323AA1AC231BA”的输出)。

这是一个结果:

TDEA KeyWrapping with Java version: 11.0.6+8-b520.43
pt        : ef7da3da918d0679
ctExpected: 7a72bbca3aa323aa1ac231ba
ct JCE    : 77d34a462f7e1fc628692ef05be251b4d8838510fe3d019b
dt JCE    : ef7da3da918d0679
ct JCE 2  : 23aa07d07bd21c3aaf6e23cbbf00cf2b3c2d140b4668f7ec
dt JCE 2  : ef7da3da918d0679
源代码:

import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

public class KeyWrappingTDEA {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException {
        System.out.println("\nTDEA KeyWrapping with Java version: " + Runtime.version());

        // testvector from TKW_AE.txt
        // testvectors: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/kwtestvectors.zip
        byte[] key = hexStringToByteArray("12b84c663120c196f8fc17428bc86a110d92cc7c4d3cb695");
        byte[] pt =  hexStringToByteArray("ef7da3da918d0679");
        byte[] ctExp =  hexStringToByteArray("7a72bbca3aa323aa1ac231ba");
        byte[] ct;
        Key dt;
        System.out.println("pt        : " + bytesToHex(pt));
        System.out.println("ctExpected: " + bytesToHex(ctExp));

        // jce
        SecretKeySpec keySpecJce = new SecretKeySpec(key, "TripleDES");
        Cipher tdesCipherJce = Cipher.getInstance("DESedeWrap");
        tdesCipherJce.init(Cipher.WRAP_MODE, keySpecJce);
        SecretKeySpec wrapkeySpecJce = new SecretKeySpec(pt, "DES");
        ct = tdesCipherJce.wrap(wrapkeySpecJce);
        System.out.println("ct JCE    : " + bytesToHex(ct));
        // unwrap for demonstration of a working implementation
        tdesCipherJce.init(Cipher.UNWRAP_MODE, keySpecJce);
        dt = tdesCipherJce.unwrap(ct, "DES", Cipher.SECRET_KEY);
        System.out.println("dt JCE    : " + bytesToHex(dt.getEncoded()));

        // jce 2
        SecretKeySpec keySpecJce2 = new SecretKeySpec(key, "TripleDES");
        Cipher tdesCipherJce2 = Cipher.getInstance("DESedeWrap");
        tdesCipherJce2.init(Cipher.WRAP_MODE, keySpecJce2);
        SecretKeySpec wrapkeySpecJce2 = new SecretKeySpec(pt, "DES");
        ct = tdesCipherJce2.wrap(wrapkeySpecJce2);
        System.out.println("ct JCE 2  : " + bytesToHex(ct));
        // unwrap for demonstration of a working implementation
        tdesCipherJce2.init(Cipher.UNWRAP_MODE, keySpecJce2);
        dt = tdesCipherJce2.unwrap(ct, "DES", Cipher.SECRET_KEY);
        System.out.println("dt JCE 2  : " + bytesToHex(dt.getEncoded()));

    }

    private static String bytesToHex(byte[] bytes) {
        StringBuffer result = new StringBuffer();
        for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        return result.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }
}
导入javax.crypto.Cipher;
导入javax.crypto.IllegalBlockSizeException;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.spec.SecretKeySpec;
导入java.security.InvalidKeyException;
导入java.security.Key;
导入java.security.NoSuchAlgorithmException;
公共类keywrappingdea{
publicstaticvoidmain(字符串[]args)抛出NoSuchPaddingException、NoSuchAlgorithmException、InvalidKeyException、IllegalBlockSizeException{
System.out.println(“\nTDEA键包装,Java版本:“+Runtime.version()”);
//来自TKW_AE.txt的测试向量
//测试向量:https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/kwtestvectors.zip
字节[]键=hexStringToByteArray(“12b84c663120c196f8fc17428bc86a110d92cc7c4d3cb695”);
字节[]pt=hexStringToByteArray(“ef7da3da918d0679”);
字节[]ctExp=hexStringToByteArray(“7a72bbca3aa323aa1ac231ba”);
字节[]ct;
键dt;
System.out.println(“pt:+bytesToHex(pt));
System.out.println(“ctExpected:+bytesToHex(ctExp));
//jce
SecretKeySpec keySpecJce=新的SecretKeySpec(键,“三元组”);
Cipher tdesCipherJce=Cipher.getInstance(“DESedeWrap”);
tdesCipherJce.init(Cipher.WRAP_模式,keySpecJce);
SecretKeySpec wrapkeySpecJce=新的SecretKeySpec(pt,“DES”);
ct=tdesCipherJce.wrap(wrapkeySpecJce);
System.out.println(“ct JCE:+bytesToHex(ct));
//展开以演示工作实现
tdesCipherJce.init(Cipher.UNWRAP_模式,keySpecJce);
dt=tdesCipherJce.unwrap(ct,“DES”,Cipher.SECRET_KEY);
System.out.println(“dt JCE:+bytesToHex(dt.getEncoded()));
//jce 2
SecretKeySpec keySpecJce2=新的SecretKeySpec(键,“三元组”);
Cipher tdesCipherJce2=Cipher.getInstance(“DESedeWrap”);
tdesCipherJce2.init(Cipher.WRAP_模式,keySpecJce2);
SecretKeySpec wrapkeySpecJce2=新的SecretKeySpec(pt,“DES”);
ct=tdesCipherJce2.wrap(wrapkeySpecJce2);
System.out.println(“ct JCE 2:+bytesToHex(ct));
//展开以演示工作实现
tdesCipherJce2.init(Cipher.UNWRAP_模式,keySpecJce2);
dt=tdesCipherJce2.unwrap(ct,“DES”,Cipher.SECRET_KEY);
System.out.println(“dtjce2:+bytesToHex(dt.getEncoded()));
}
私有静态字符串bytesToHex(字节[]字节){
StringBuffer结果=新的StringBuffer();
for(byte b:bytes)result.append(Integer.toString((b&0xff)+0x100,16).子字符串(1));
返回result.toString();
}
公共静态字节[]hexStringToByteArray(字符串s){
int len=s.length();
字节[]数据=新字节[len/2];
对于(int i=0;i数据[i/2]=(字节)((Character.digit(s.charAt(i),16))是我,还是NIST文档引用的RFC与Java算法规范不同?输出的大小也不正确。@Maarten:我开始了使用AESWrap的密钥封装体验,并且使用SunJce“AESWrap”时,所有这些都能很好地完成。不幸的是,我找不到任何没有随机initvector且密文输出长度为(plaintextlength+4字节)的TDEAWrap算法,如NIST testvectors所示。对于Bouncy Castle,有一个可用的“Desederfc321WRAP”算法,但我得到的密文输出长度为(plaintextlength+8).对NIST一致性算法有什么想法吗?不幸的是,我没有。我甚至没有使用过密钥包装机制一次,我也不赞成它们。对于AES,我会使用AES-GCM-SIV,但对于TDEA这样的8字节分组密码,这是不可用的。@Maarten:这是离题的-AES-GCM-SIV使用哪个库(我成功地运行了一些测试)?是否有计划在未来向Bouncy Castle添加AES-GCM-SIV)?我目前不支持。最好在Bouncy castle dev邮件列表中询问Bouncy是否支持。但老实说,如果他们能够获得源代码提交,他们会更加感激。是我,还是NIST文档引用的RFC与Java算法规范不同?输出的大小也不正确。@Maarten:我开始了我的研究AESWrap的密钥封装经验以及SunJce“AESWrap”的开箱即用性都很好。不幸的是,如果没有随机初始向量和密文输出长度(明文长度+4字节),我找不到TDEAWrap的任何算法,如NIST测试向量所示。对于Bouncy Castle,有一个“Desederfc321wrap”算法可用,但我得到了一个密文输出长度(plaintextlength+8)。对NIST一致算法有什么想法吗?不幸的是,我没有。我甚至没有使用过密钥包装机制一次,我也不赞成它们。对于AES,我会使用AES-GCM-SIV,但那不是
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

public class KeyWrappingTDEA {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException {
        System.out.println("\nTDEA KeyWrapping with Java version: " + Runtime.version());

        // testvector from TKW_AE.txt
        // testvectors: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/mac/kwtestvectors.zip
        byte[] key = hexStringToByteArray("12b84c663120c196f8fc17428bc86a110d92cc7c4d3cb695");
        byte[] pt =  hexStringToByteArray("ef7da3da918d0679");
        byte[] ctExp =  hexStringToByteArray("7a72bbca3aa323aa1ac231ba");
        byte[] ct;
        Key dt;
        System.out.println("pt        : " + bytesToHex(pt));
        System.out.println("ctExpected: " + bytesToHex(ctExp));

        // jce
        SecretKeySpec keySpecJce = new SecretKeySpec(key, "TripleDES");
        Cipher tdesCipherJce = Cipher.getInstance("DESedeWrap");
        tdesCipherJce.init(Cipher.WRAP_MODE, keySpecJce);
        SecretKeySpec wrapkeySpecJce = new SecretKeySpec(pt, "DES");
        ct = tdesCipherJce.wrap(wrapkeySpecJce);
        System.out.println("ct JCE    : " + bytesToHex(ct));
        // unwrap for demonstration of a working implementation
        tdesCipherJce.init(Cipher.UNWRAP_MODE, keySpecJce);
        dt = tdesCipherJce.unwrap(ct, "DES", Cipher.SECRET_KEY);
        System.out.println("dt JCE    : " + bytesToHex(dt.getEncoded()));

        // jce 2
        SecretKeySpec keySpecJce2 = new SecretKeySpec(key, "TripleDES");
        Cipher tdesCipherJce2 = Cipher.getInstance("DESedeWrap");
        tdesCipherJce2.init(Cipher.WRAP_MODE, keySpecJce2);
        SecretKeySpec wrapkeySpecJce2 = new SecretKeySpec(pt, "DES");
        ct = tdesCipherJce2.wrap(wrapkeySpecJce2);
        System.out.println("ct JCE 2  : " + bytesToHex(ct));
        // unwrap for demonstration of a working implementation
        tdesCipherJce2.init(Cipher.UNWRAP_MODE, keySpecJce2);
        dt = tdesCipherJce2.unwrap(ct, "DES", Cipher.SECRET_KEY);
        System.out.println("dt JCE 2  : " + bytesToHex(dt.getEncoded()));

    }

    private static String bytesToHex(byte[] bytes) {
        StringBuffer result = new StringBuffer();
        for (byte b : bytes) result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        return result.toString();
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }
}