Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/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 错误的AES加密_Java_Encryption_Cryptography_Aes_Hmacsha1 - Fatal编程技术网

Java 错误的AES加密

Java 错误的AES加密,java,encryption,cryptography,aes,hmacsha1,Java,Encryption,Cryptography,Aes,Hmacsha1,我正在尝试使用一个简单的AES加密工具,将明文密码转换为PSKC5XML,如中所示。使用其中所示的示例值,即: 机密:31323334353637383933031323334353637383939330 加密密钥:123456789012134567890123456789012 MAC密钥:112233445667788990011223344556677889900 HOTP的IV:000102030405060708090A0B0C0E0F 四、MAC:112233445667788

我正在尝试使用一个简单的AES加密工具,将明文密码转换为PSKC5XML,如中所示。使用其中所示的示例值,即:

  • 机密:31323334353637383933031323334353637383939330
  • 加密密钥:123456789012134567890123456789012
  • MAC密钥:112233445667788990011223344556677889900
  • HOTP的IV:000102030405060708090A0B0C0E0F
  • 四、MAC:1122334456677889900112233445566
但是AES摘要的IV太长,MAC类不接受用于签名的IV。我试图忽略MAC-IV,将HOTP-IV转换为

{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
但我得到的结果与示例中所示的不同。这是我正在使用的类:

import java.math.BigInteger;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.sun.org.apache.xml.internal.security.utils.Base64;

public class Encrypt {
    private byte[] ivMac, ivHotp, sharedKey, macKey;
    private SecretKey secretSharedKey, secretMacKey;
    private Cipher cipher;
    private AlgorithmParameterSpec cipherParamSpec;
    private Mac mac;

    public Encrypt(String encryptionKey, String macKey, String ivMac, String ivHotp, String csvFilePath) throws FileNotFoundException {
        try {
            this.ivMac = hexStr2Bytes(ivMac);
            this.ivHotp = hexStr2Bytes(ivHotp);
            this.sharedKey = hexStr2Bytes(encryptionKey);
            this.macKey = hexStr2Bytes(macKey);         
            this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            this.mac = Mac.getInstance("HmacSHA1");
            this.mac.init(new SecretKeySpec(this.macKey, "HmacSHA1"));          
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void encryptSingleSecret(String serialNo, String secret) {
        try {
            byte[] secretBytes = hexStr2Bytes(secret);
            String macKeyString = Base64.encode(macKey);
            cipherParamSpec = new IvParameterSpec(this.ivHotp);
            cipher.init(Cipher.ENCRYPT_MODE, new     SecretKeySpec(this.sharedKey, "AES"), cipherParamSpec);
            byte[] secretDigested = cipher.doFinal(secretBytes);
            cipherParamSpec = new IvParameterSpec(this.ivMac);
            cipher.init(Cipher.ENCRYPT_MODE, new     SecretKeySpec(this.sharedKey, "AES"), cipherParamSpec);
            byte[] macDigested = cipher.doFinal(macKey);
            String MacEncrypted = Base64.encode(macDigested);
            String SecretEncrypted = Base64.encode(secretDigested);
            String MacValue =     Base64.encode(mac.doFinal(secretDigested));
            System.out.println("MAC Key: " + MacEncrypted);
            System.out.println("Secret: " + SecretEncrypted);
            System.out.println("MAC ValueMac: " + MacValue);
            return;
        } catch (Exception ex) {
            ex.printStackTrace();
            return;
        }
    }

    /**
     * From RFC 6238 App. A
     * @param hex
     * @return
     */
    public byte[] hexStr2Bytes(String hex) {
        // Adding one byte to get the right conversion
        // Values starting with "0" can be converted
        byte[] bArray = new BigInteger("10" + hex,16).toByteArray();

        // Copy all the REAL bytes, not the "first"
        byte[] ret = new byte[bArray.length - 1];
        for (int i = 0; i < ret.length; i++)
            ret[i] = bArray[i+1];
        return ret;
    }
}
import java.math.biginger;
导入javax.crypto.Cipher;
导入javax.crypto.Mac;
导入java.security.spec.AlgorithmParameterSpec;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.SecretKeySpec;
导入com.sun.org.apache.xml.internal.security.utils.Base64;
公共类加密{
私有字节[]ivMac、ivHotp、sharedKey、macKey;
私密密钥secretSharedKey,secretMacKey;
专用密码;
私有算法参数规范cipherParamSpec;
专用Mac;
公共加密(String encryptionKey、String macKey、String ivMac、String ivHotp、String csvFilePath)引发FileNotFoundException{
试一试{
this.ivMac=hexStr2Bytes(ivMac);
this.ivHotp=hexStr2Bytes(ivHotp);
this.sharedKey=hexStr2Bytes(encryptionKey);
this.macKey=hexStr2Bytes(macKey);
this.cipher=cipher.getInstance(“AES/CBC/PKCS5Padding”);
this.mac=mac.getInstance(“HmacSHA1”);
this.mac.init(新的SecretKeySpec(this.macKey,“HmacSHA1”);
}捕获(例外情况除外){
例如printStackTrace();
}
}
public void encryptSingleSecret(字符串序列号,字符串机密){
试一试{
byte[]secretBytes=hexStr2Bytes(secret);
字符串macKeyString=Base64.encode(macKey);
cipherParamSpec=新的IvParameterSpec(this.ivHotp);
cipher.init(cipher.ENCRYPT_模式,新的SecretKeySpec(this.sharedKey,“AES”),cipherParamSpec);
字节[]secretDigested=cipher.doFinal(secretBytes);
cipherParamSpec=新的IvParameterSpec(this.ivMac);
cipher.init(cipher.ENCRYPT_模式,新的SecretKeySpec(this.sharedKey,“AES”),cipherParamSpec);
字节[]macDigested=cipher.doFinal(macKey);
字符串MacEncrypted=Base64.encode(macDigested);
字符串secretincrypted=Base64.encode(secretDigested);
字符串MacValue=Base64.encode(mac.doFinal(secretDigested));
System.out.println(“MAC键:+MacEncrypted”);
System.out.println(“秘密:+秘密加密);
System.out.println(“MAC-ValueMac:+MAC-value”);
返回;
}捕获(例外情况除外){
例如printStackTrace();
返回;
}
}
/**
*来自RFC 6238附录A
*@param十六进制
*@返回
*/
公共字节[]hexStr2Bytes(字符串十六进制){
//添加一个字节以获得正确的转换
//可以转换以“0”开头的值
byte[]baray=新的BigInteger(“10”+十六进制,16).toByteArray();
//复制所有实际字节,而不是“第一个”
字节[]ret=新字节[bArray.length-1];
对于(int i=0;i
我做错了什么


更新:这两个IV分别是我用来加密机密和MAC密钥的IV,它们是十六进制数组,但我的结果与示例中显示的不同。有什么线索吗?

我想你对什么被加密、编码等有点困惑。我添加了一个简单的方法
concatbytearray
,然后我重写了你的
encryptSingleSecret
方法(见下文)。你遗漏了一件事,那就是你必须将用来加密结果密码的IV预先加好,然后base64对整个shebang进行编码。你对MAC部分的理解也有点偏差

private byte [] concatByteArrays(byte []a, byte [] b ) {
    byte [] result = new byte[a.length + b.length];
    System.arraycopy(a, 0, result, 0, a.length);
    System.arraycopy(b, 0, result, a.length, b.length);
    return result;
}

public void encryptSingleSecret(String serialNo, String secret) {
    try {
        byte[] secretBytes = hexStr2Bytes(secret);

        // First, encrypt the MAC key

        cipherParamSpec = new IvParameterSpec(this.ivMac);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(this.sharedKey, "AES"),
                cipherParamSpec);
        byte[] encryptedMacKey = cipher.doFinal(this.macKey);

        // Now, prepend the IV used to encrypt the mac key to the cipher

        byte [] toBeBase64Encoded = concatByteArrays(this.ivMac, encryptedMacKey);

        // Now base64-encode the result and print it out. This is for the
        // <MACKey> element

        System.out.println("<MACKey> <CipherValue>: " + Base64.encode(toBeBase64Encoded));

        // Next, encrypt the secret

        cipherParamSpec = new IvParameterSpec(this.ivHotp);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(this.sharedKey, "AES"),
                cipherParamSpec);
        byte[] encryptedSecret = cipher.doFinal(secretBytes);

        // Now, prepend the IV used to encrypt the secret to the cipher

        toBeBase64Encoded = concatByteArrays(this.ivHotp, encryptedSecret); 

        // Now base64-encode the result and print it out. This is for the
        // <Data> element

        System.out.println("<Data><Secret><CipherValue>: " + Base64.encode(toBeBase64Encoded));

        // Finally, compute the MAC over the encrypted value

        byte [] macValue = this.mac.doFinal(toBeBase64Encoded);

        // Base64-encode the result and print it out. This is for the
        // ValueMAC element

        System.out.println("<Data><Secret><ValueMAC>: " + Base64.encode(macValue));

        return;
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
private byte[]concatbytearray(byte[]a,byte[]b){
字节[]结果=新字节[a.length+b.length];
数组复制(a,0,result,0,a.length);
数组复制(b,0,结果,a.长度,b.长度);
返回结果;
}
public void encryptSingleSecret(字符串序列号,字符串机密){
试一试{
byte[]secretBytes=hexStr2Bytes(secret);
//首先,加密MAC密钥
cipherParamSpec=新的IvParameterSpec(this.ivMac);
cipher.init(cipher.ENCRYPT_模式,新的SecretKeySpec(this.sharedKey,“AES”),
密码规范);
字节[]encryptedMacKey=cipher.doFinal(this.macKey);
//现在,将用于加密mac密钥的IV前置到密码
字节[]toBeBase64Encoded=concatbytearray(this.ivMac,encryptedMacKey);
//现在base64对结果进行编码并打印出来
//元素
System.out.println(“:”+Base64.encode(toBeBase64Encoded));
//接下来,加密这个秘密
cipherParamSpec=新的IvParameterSpec(this.ivHotp);
cipher.init(cipher.ENCRYPT_模式,新的SecretKeySpec(this.sharedKey,“AES”),
密码规范);
字节[]encryptedSecret=cipher.doFinal(secretBytes);
//现在,在密码前加上用来加密密码的IV
toBeBase64Encoded=concatbyteArray(this.ivHotp,encryptedSecret);
//现在base64对结果进行编码并打印出来
//元素
System.out.println(“:”+Base64.encode(toBeBase64Encoded));
//最后,计算加密值上的MAC
字节[]macValue=this.mac.doFinal(toBeBase64Encoded);