我正在测试Diffie-Hellman KeyAgreement算法。并使用它来生成密钥。但在我得到SecretKeySpec
之后,我遇到了使用它来初始化Cipher
的问题。这是我的代码:
package ggicci.infosec;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.KeyAgreement;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Diffie-Hellman module for demonstrating KeyAgreement Algorithm
* @author Ggicci
* @since 2013.01.09
*/
public class DiffieHellmanModule {
private static final byte[] skip1024ModulusBytes = { (byte) 0xF4,
(byte) 0x88, (byte) 0xFD, (byte) 0x58, (byte) 0x4E, (byte) 0x49,
(byte) 0xDB, (byte) 0xCD, (byte) 0x20, (byte) 0xB4, (byte) 0x9D,
(byte) 0xE4, (byte) 0x91, (byte) 0x07, (byte) 0x36, (byte) 0x6B,
(byte) 0x33, (byte) 0x6C, (byte) 0x38, (byte) 0x0D, (byte) 0x45,
(byte) 0x1D, (byte) 0x0F, (byte) 0x7C, (byte) 0x88, (byte) 0xB3,
(byte) 0x1C, (byte) 0x7C, (byte) 0x5B, (byte) 0x2D, (byte) 0x8E,
(byte) 0xF6, (byte) 0xF3, (byte) 0xC9, (byte) 0x23, (byte) 0xC0,
(byte) 0x43, (byte) 0xF0, (byte) 0xA5, (byte) 0x5B, (byte) 0x18,
(byte) 0x8D, (byte) 0x8E, (byte) 0xBB, (byte) 0x55, (byte) 0x8C,
(byte) 0xB8, (byte) 0x5D, (byte) 0x38, (byte) 0xD3, (byte) 0x34,
(byte) 0xFD, (byte) 0x7C, (byte) 0x17, (byte) 0x57, (byte) 0x43,
(byte) 0xA3, (byte) 0x1D, (byte) 0x18, (byte) 0x6C, (byte) 0xDE,
(byte) 0x33, (byte) 0x21, (byte) 0x2C, (byte) 0xB5, (byte) 0x2A,
(byte) 0xFF, (byte) 0x3C, (byte) 0xE1, (byte) 0xB1, (byte) 0x29,
(byte) 0x40, (byte) 0x18, (byte) 0x11, (byte) 0x8D, (byte) 0x7C,
(byte) 0x84, (byte) 0xA7, (byte) 0x0A, (byte) 0x72, (byte) 0xD6,
(byte) 0x86, (byte) 0xC4, (byte) 0x03, (byte) 0x19, (byte) 0xC8,
(byte) 0x07, (byte) 0x29, (byte) 0x7A, (byte) 0xCA, (byte) 0x95,
(byte) 0x0C, (byte) 0xD9, (byte) 0x96, (byte) 0x9F, (byte) 0xAB,
(byte) 0xD0, (byte) 0x0A, (byte) 0x50, (byte) 0x9B, (byte) 0x02,
(byte) 0x46, (byte) 0xD3, (byte) 0x08, (byte) 0x3D, (byte) 0x66,
(byte) 0xA4, (byte) 0x5D, (byte) 0x41, (byte) 0x9F, (byte) 0x9C,
(byte) 0x7C, (byte) 0xBD, (byte) 0x89, (byte) 0x4B, (byte) 0x22,
(byte) 0x19, (byte) 0x26, (byte) 0xBA, (byte) 0xAB, (byte) 0xA2,
(byte) 0x5E, (byte) 0xC3, (byte) 0x55, (byte) 0xE9, (byte) 0x2F,
(byte) 0x78, (byte) 0xC7 };
private static final BigInteger skip1024Modulus;
private static final BigInteger skip1024Base;
private static KeyPairGenerator kpg;
static {
skip1024Modulus = new BigInteger(1, skip1024ModulusBytes);
skip1024Base = BigInteger.valueOf(2);
try {
kpg = KeyPairGenerator.getInstance("DH");
DHParameterSpec dhp = new DHParameterSpec(skip1024Modulus,
skip1024Base);
kpg.initialize(dhp);
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
}
/**
* Create KeyAgreement and generate secret key
*
* @param prk_self
* the private key from the user who wants to generate the secret
* key
* @param pbk_peer
* the public key from the user whom is to be agree on the secret
* key with
* @param lastPhase
* flag which indicates whether or not this is the last phase of
* this key agreement
* @return the secret key
*/
public static SecretKeySpec agreeSecretKey(PrivateKey prk_self,
PublicKey pbk_peer, boolean lastPhase) throws Exception {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(prk_self);
ka.doPhase(pbk_peer, lastPhase);
byte[] bkey = ka.generateSecret();
return new SecretKeySpec(bkey, "AES");
}
/**
* Generate a key pair of algorithm "DiffieHellman"
*
* @return the public and private key pair
*/
public static KeyPair genDHKeyPair() {
return kpg.genKeyPair();
}
}
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import ggicci.infosec.DiffieHellmanModule;
public class DHTest {
public static void main(String[] args) {
KeyPair kp1 = DiffieHellmanModule.genDHKeyPair();
KeyPair kp2 = DiffieHellmanModule.genDHKeyPair();
PublicKey pbk1 = kp1.getPublic();
PublicKey pbk2 = kp2.getPublic();
PrivateKey prk1 = kp1.getPrivate();
PrivateKey prk2 = kp2.getPrivate();
try {
SecretKeySpec sk1 = DiffieHellmanModule.agreeSecretKey(prk1, pbk2, true);
SecretKeySpec sk2 = DiffieHellmanModule.agreeSecretKey(prk2, pbk1, true);
Cipher cipher = Cipher.getInstance(sk1.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, sk1); //-->Exception here:Invalid AES key length: 128 bytes
byte[] ciphertext = cipher.doFinal("Hello World".getBytes("utf-8"));
cipher.init(Cipher.DECRYPT_MODE, sk2);
System.out.println("Decrypted: " + new String(cipher.doFinal(ciphertext), "utf-8"));
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
您正在使用语句byte[] bkey = ka.generateSecret();
生成128字节的DiffieHellman密钥的关键数据,但随后将其用作具有new SecretKeySpec(bkey, "AES");
稍后会触发您尝试使用cipher.init(Cipher.ENCRYPT_MODE, sk1);
初始化密码时看到的异常,因为AES密钥应该具有16,24或32字节(128,192或256位)的密钥数据,而不是128字节。