下面列出了javax.crypto.SecretKey#getEncoded ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 生成加密秘钥
*
* @return
*/
private static SecretKeySpec getSecretKey(final String password) {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
//AES 要求密钥长度为 128
kg.init(128, new SecureRandom(password.getBytes()));
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof SecretKey))
return false;
SecretKey that = (SecretKey) obj;
if (!(that.getAlgorithm().equalsIgnoreCase(getAlgorithm())))
return false;
if (!(that.getFormat().equalsIgnoreCase("RAW")))
return false;
byte[] thatEncoded = that.getEncoded();
boolean ret = Arrays.equals(key, that.getEncoded());
java.util.Arrays.fill(thatEncoded, (byte)0x00);
return ret;
}
/**
* 生成AES密钥
*/
public static SecretKeySpec createKey() {
try {
//指定加密算法的名称为AES,
KeyGenerator keyGenerator = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM);
//初始化密钥生成器,指定密钥的长度(单位:bit),
//SecureRandom是生成安全随机数序列
SecureRandom secureRandom = new SecureRandom(key.getBytes());
keyGenerator.init(128, secureRandom);
//生成原始对称密钥
SecretKey secretKey = keyGenerator.generateKey();
//返回编码格式的密钥
byte[] enCodeFormat = secretKey.getEncoded();
//根据字节数组生成AES专用密钥
SecretKeySpec aesKeySpec = getSecretKey(enCodeFormat);
//返回AES密钥
return aesKeySpec;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof SecretKey))
return false;
SecretKey that = (SecretKey)obj;
if (!(that.getAlgorithm().equalsIgnoreCase(type)))
return false;
byte[] thatEncoded = that.getEncoded();
boolean ret = java.util.Arrays.equals(this.key, thatEncoded);
java.util.Arrays.fill(thatEncoded, (byte)0x00);
return ret;
}
public AESPayloadCodec(CryptoConfig cryptoConfig) {
try {
AeadConfig.register();
SecretKey secretKey = deriveKey(cryptoConfig);
aead = new AesGcmJce(secretKey.getEncoded());
} catch (GeneralSecurityException e) {
throw new RuntimeException("Error while starting AESPayloadCodec", e);
}
}
/**
* 生成一个密钥
*
* @return 密钥的二进制形式
*/
public byte[] initKey() {
KeyGenerator kg = getKeyGenerator();
kg.init(getConfiguration().getKeySize());
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
/**
* 初始化HmacSHA1密钥
*
* @return
* @throws Exception
*/
public static byte[] initHmacSHAKey() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HMacTiger");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
/**
* Decrypt an integer from a String.
*
* @param encrypted
* @param context
* @return
* @throws ServletException
*/
private static Integer decryptInteger(String encrypted, ServletContext context) throws ServletException {
String encryptedParts[] = encrypted.split("\\|");
if (encryptedParts.length != 3) {
throw new ServletException("Invalid encrypted string.");
}
/* Get password. */
String password = context.getInitParameter("SampleSetIDEncryptionPassword");
/* Extract the encrypted data, initialisation vector, and salt from the cookie. */
Decoder decoder = Base64.getDecoder();
byte ciphertext[] = decoder.decode(encryptedParts[0]);
byte iv[] = decoder.decode(encryptedParts[1]);
byte salt[] = decoder.decode(encryptedParts[2]);
byte plainbytes[];
try {
/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
plainbytes = cipher.doFinal(ciphertext);
} catch (Exception ex) {
throw new ServletException(ex);
}
return ByteBuffer.wrap(plainbytes).asIntBuffer().get();
}
/**
* 生成AES密钥,可选长度为128,192,256位.
*/
public static byte[] generateAesKey(int keysize) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(keysize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (GeneralSecurityException e) {
throw ExceptionUtils.unchecked(e);
}
}
/**
* 生成AES密钥,可选长度为128,192,256位.
*/
public static byte[] generateAesKey(int keysize) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(AES);
keyGenerator.init(keysize);
SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (GeneralSecurityException e) {
throw Exceptions.unchecked(e);
}
}
private static void test(KeyGenerator kg,
int clientVersion, int serverVersion) throws Exception {
System.out.printf(
"Testing RSA pre-master secret key generation between " +
"client (0x%04X) and server(0x%04X)%n",
clientVersion, serverVersion);
kg.init(new TlsRsaPremasterSecretParameterSpec(
clientVersion, serverVersion));
SecretKey key = kg.generateKey();
byte[] encoded = key.getEncoded();
if (encoded != null) { // raw key material may be not extractable
if (encoded.length != 48) {
throw new Exception("length: " + encoded.length);
}
int v = versionOf(encoded[0], encoded[1]);
if (clientVersion != v) {
if (serverVersion != v || clientVersion >= 0x0302) {
throw new Exception(String.format(
"version mismatch: (0x%04X) rather than (0x%04X) " +
"is used in pre-master secret", v, clientVersion));
}
System.out.printf("Use compatible version (0x%04X)%n", v);
}
System.out.println("Passed, version matches!");
} else {
System.out.println("Raw key material is not extractable");
}
}
public static byte[] generateKey() {
try {
final KeyGenerator keyGenerator = KeyGenerator.getInstance(PasswordUtilities.ALG);
final SecretKey secretKey = keyGenerator.generateKey();
return secretKey.getEncoded();
} catch (final NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
/**
* @param kekMaterials non-null encryption materials
*/
protected final SecretKey generateCEK(final EncryptionMaterials kekMaterials,
final Provider providerIn) {
final String keygenAlgo = contentCryptoScheme.getKeyGeneratorAlgorithm();
KeyGenerator generator;
try {
generator = providerIn == null ? KeyGenerator.getInstance(keygenAlgo)
: KeyGenerator.getInstance(keygenAlgo, providerIn);
generator.init(contentCryptoScheme.getKeyLengthInBits(),
cryptoScheme.getSecureRandom());
// Set to true if the key encryption involves the use of BC's public key
boolean involvesBCPublicKey = false;
KeyPair keypair = kekMaterials.getKeyPair();
if (keypair != null) {
String keyWrapAlgo =
cryptoScheme.getKeyWrapScheme().getKeyWrapAlgorithm(keypair.getPublic());
if (keyWrapAlgo == null) {
Provider provider = generator.getProvider();
String providerName = provider == null ? null : provider.getName();
involvesBCPublicKey = CryptoRuntime.BOUNCY_CASTLE_PROVIDER.equals(providerName);
}
}
SecretKey secretKey = generator.generateKey();
if (!involvesBCPublicKey || secretKey.getEncoded()[0] != 0)
return secretKey;
for (int retry = 0; retry < 10; retry++) {
secretKey = generator.generateKey();
if (secretKey.getEncoded()[0] != 0)
return secretKey;
}
// The probability of getting here is 2^80, which is impossible in practice.
throw new CosClientException("Failed to generate secret key");
} catch (NoSuchAlgorithmException e) {
throw new CosClientException(
"Unable to generate envelope symmetric key:" + e.getMessage(), e);
}
}
/**
* 初始化HmacSHA256密钥
*
* @return
* @throws Exception
*/
public static byte[] initHmacSHA256Key() throws Exception {
// 初始化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
// 产生秘密密钥
SecretKey secretKey = keyGenerator.generateKey();
// 获得密钥
return secretKey.getEncoded();
}
private static void test(KeyGenerator kg,
int clientVersion, int serverVersion) throws Exception {
System.out.printf(
"Testing RSA pre-master secret key generation between " +
"client (0x%04X) and server(0x%04X)%n",
clientVersion, serverVersion);
kg.init(new TlsRsaPremasterSecretParameterSpec(
clientVersion, serverVersion));
SecretKey key = kg.generateKey();
byte[] encoded = key.getEncoded();
if (encoded != null) { // raw key material may be not extractable
if (encoded.length != 48) {
throw new Exception("length: " + encoded.length);
}
int v = versionOf(encoded[0], encoded[1]);
if (clientVersion != v) {
if (serverVersion != v || clientVersion >= 0x0302) {
throw new Exception(String.format(
"version mismatch: (0x%04X) rather than (0x%04X) " +
"is used in pre-master secret", v, clientVersion));
}
System.out.printf("Use compatible version (0x%04X)%n", v);
}
System.out.println("Passed, version matches!");
} else {
System.out.println("Raw key material is not extractable");
}
}
public byte[] generateKey( int keySize ) throws CryptoKeyException {
try {
// Get a key generator for algorithm
KeyGenerator kg = KeyGenerator.getInstance( meta.getAlgorithm() );
// SecureRandom random = new SecureRandom();
kg.init( keySize );
// Use it to generate a key
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
} catch ( Exception e ) {
throw new CryptoKeyException( e );
}
}
public static void main(String[] args) throws Exception {
Provider provider = Security.getProvider("SunJCE");
InputStream in = new FileInputStream(new File(BASE, "prf12data.txt"));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
int n = 0;
int lineNumber = 0;
byte[] secret = null;
String label = null;
byte[] seed = null;
int length = 0;
String prfAlg = null;
int prfHashLength = 0;
int prfBlockSize = 0;
byte[] output = null;
while (true) {
String line = reader.readLine();
lineNumber++;
if (line == null) {
break;
}
if (line.startsWith("prf-") == false) {
continue;
}
String data = line.substring(PREFIX_LENGTH);
if (line.startsWith("prf-secret:")) {
secret = parse(data);
} else if (line.startsWith("prf-label:")) {
label = data;
} else if (line.startsWith("prf-seed:")) {
seed = parse(data);
} else if (line.startsWith("prf-length:")) {
length = Integer.parseInt(data);
} else if (line.startsWith("prf-alg:")) {
prfAlg = data;
switch (prfAlg) {
case "SHA-224":
prfHashLength = 28;
prfBlockSize = 64;
break;
case "SHA-256":
prfHashLength = 32;
prfBlockSize = 64;
break;
case "SHA-384":
prfHashLength = 48;
prfBlockSize = 128;
break;
case "SHA-512":
prfHashLength = 64;
prfBlockSize = 128;
break;
default:
throw new Exception("Unknown Alg in the data.");
}
} else if (line.startsWith("prf-output:")) {
output = parse(data);
System.out.print(".");
n++;
KeyGenerator kg =
KeyGenerator.getInstance("SunTls12Prf", provider);
SecretKey inKey;
if (secret == null) {
inKey = null;
} else {
inKey = new SecretKeySpec(secret, "Generic");
}
TlsPrfParameterSpec spec =
new TlsPrfParameterSpec(inKey, label, seed, length,
prfAlg, prfHashLength, prfBlockSize);
kg.init(spec);
SecretKey key = kg.generateKey();
byte[] enc = key.getEncoded();
if (Arrays.equals(output, enc) == false) {
throw new Exception("mismatch line: " + lineNumber);
}
} else {
throw new Exception("Unknown line: " + line);
}
}
if (n == 0) {
throw new Exception("no tests");
}
in.close();
System.out.println();
System.out.println("OK: " + n + " tests");
}
private void runTest(String mo, String pad, int keySize)
throws NoSuchPaddingException, BadPaddingException,
ShortBufferException, IllegalBlockSizeException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException {
String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad;
out.println("Testing: " + TRANSFORMATION);
// Initialization
Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE);
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE);
if (keySize != 0) {
kg.init(keySize);
}
SecretKey key = kg.generateKey();
SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
AlgorithmParameterSpec aps = new IvParameterSpec(IV);
if (mo.equalsIgnoreCase("ECB")) {
ci.init(Cipher.ENCRYPT_MODE, key);
} else {
ci.init(Cipher.ENCRYPT_MODE, key, aps);
}
// Encryption
byte[] plainText = INPUT_TEXT.clone();
// Generate cipher and save to separate buffer
byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
// Generate cipher and save to same buffer
int enc_bytes = ci.update(
INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
if (!equalsBlock(
INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
cipherText, 0, cipherText.length)) {
throw new RuntimeException(
"Different ciphers generated with same buffer");
}
// Decryption
if (mo.equalsIgnoreCase("ECB")) {
ci.init(Cipher.DECRYPT_MODE, skeySpec);
} else {
ci.init(Cipher.DECRYPT_MODE, skeySpec, aps);
}
// Recover text from cipher and save to separate buffer
byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
if (!equalsBlock(
plainText, ENC_OFFSET, TEXT_LEN,
recoveredText, 0, recoveredText.length)) {
throw new RuntimeException(
"Recovered text not same as plain text");
} else {
out.println("Recovered and plain text are same");
}
// Recover text from cipher and save to same buffer
int dec_bytes = ci.update(
INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
if (!equalsBlock(
plainText, ENC_OFFSET, TEXT_LEN,
INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
throw new RuntimeException(
"Recovered text not same as plain text with same buffer");
} else {
out.println("Recovered and plain text are same with same buffer");
}
out.println("Test Passed.");
}
public void main(Provider provider) throws Exception {
if (provider.getService("KeyGenerator", "SunTlsPrf") == null) {
System.out.println("Provider does not support algorithm, skipping");
return;
}
InputStream in = new FileInputStream(new File(BASE, "prfdata.txt"));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
int n = 0;
int lineNumber = 0;
byte[] secret = null;
String label = null;
byte[] seed = null;
int length = 0;
byte[] output = null;
while (true) {
String line = reader.readLine();
lineNumber++;
if (line == null) {
break;
}
if (line.startsWith("prf-") == false) {
continue;
}
String data = line.substring(PREFIX_LENGTH);
if (line.startsWith("prf-secret:")) {
secret = parse(data);
} else if (line.startsWith("prf-label:")) {
label = data;
} else if (line.startsWith("prf-seed:")) {
seed = parse(data);
} else if (line.startsWith("prf-length:")) {
length = Integer.parseInt(data);
} else if (line.startsWith("prf-output:")) {
output = parse(data);
System.out.print(".");
n++;
KeyGenerator kg =
KeyGenerator.getInstance("SunTlsPrf", provider);
SecretKey inKey;
if (secret == null) {
inKey = null;
} else {
inKey = new SecretKeySpec(secret, "Generic");
}
TlsPrfParameterSpec spec =
new TlsPrfParameterSpec(inKey, label, seed, length,
null, -1, -1);
SecretKey key;
try {
kg.init(spec);
key = kg.generateKey();
} catch (Exception e) {
if (secret == null) {
// This fails on Solaris, but since we never call this
// API for this case in JSSE, ignore the failure.
// (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE
// mechanism)
System.out.print("X");
continue;
}
System.out.println();
throw new Exception("Error on line: " + lineNumber, e);
}
byte[] enc = key.getEncoded();
if (Arrays.equals(output, enc) == false) {
System.out.println();
System.out.println("expected: " + toString(output));
System.out.println("actual: " + toString(enc));
throw new Exception("mismatch line: " + lineNumber);
}
} else {
throw new Exception("Unknown line: " + line);
}
}
if (n == 0) {
throw new Exception("no tests");
}
in.close();
System.out.println();
System.out.println("OK: " + n + " tests");
}
private void runTest(String mo, String pad, int keySize)
throws NoSuchPaddingException, BadPaddingException,
ShortBufferException, IllegalBlockSizeException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchProviderException {
String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad;
out.println("Testing: " + TRANSFORMATION);
// Initialization
Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE);
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE);
if (keySize != 0) {
kg.init(keySize);
}
SecretKey key = kg.generateKey();
SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
AlgorithmParameterSpec aps = new IvParameterSpec(IV);
if (mo.equalsIgnoreCase("ECB")) {
ci.init(Cipher.ENCRYPT_MODE, key);
} else {
ci.init(Cipher.ENCRYPT_MODE, key, aps);
}
// Encryption
byte[] plainText = INPUT_TEXT.clone();
// Generate cipher and save to separate buffer
byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
// Generate cipher and save to same buffer
int enc_bytes = ci.update(
INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
if (!equalsBlock(
INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
cipherText, 0, cipherText.length)) {
throw new RuntimeException(
"Different ciphers generated with same buffer");
}
// Decryption
if (mo.equalsIgnoreCase("ECB")) {
ci.init(Cipher.DECRYPT_MODE, skeySpec);
} else {
ci.init(Cipher.DECRYPT_MODE, skeySpec, aps);
}
// Recover text from cipher and save to separate buffer
byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
if (!equalsBlock(
plainText, ENC_OFFSET, TEXT_LEN,
recoveredText, 0, recoveredText.length)) {
throw new RuntimeException(
"Recovered text not same as plain text");
} else {
out.println("Recovered and plain text are same");
}
// Recover text from cipher and save to same buffer
int dec_bytes = ci.update(
INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
if (!equalsBlock(
plainText, ENC_OFFSET, TEXT_LEN,
INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
throw new RuntimeException(
"Recovered text not same as plain text with same buffer");
} else {
out.println("Recovered and plain text are same with same buffer");
}
out.println("Test Passed.");
}