下面列出了javax.crypto.KeyGenerator#init ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void addaccesskey(String keystorelocation, String password) throws Exception {
KeyStore keystore = KeyStore.getInstance("BCFKS", BC_FIPS_PROVIDER);
keystore.load(new FileInputStream(keystorelocation), password.toCharArray());
KeyGenerator keygen = KeyGenerator.getInstance("AES", BC_FIPS_PROVIDER);
keygen.init(128);
SecretKey sk = keygen.generateKey();
String secretkey = Hex.toHexString(sk.getEncoded());
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(new Date().toString().getBytes());
String accesskey = Hex.toHexString(digest.digest()).substring(0, 16);
keystore.setKeyEntry(accesskey, sk, password.toCharArray(), null);
keystore.store(new FileOutputStream(keystorelocation), password.toCharArray());
System.out.println("Created new access/secret key:");
System.out.println("Access key:" + accesskey);
System.out.println("Secret key:" + secretkey);
}
/**
* 获取256位的加密密钥
* @param seed
* @return
* @throws Exception
*/
@SuppressLint("TrulyRandom")
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = null;
// 在4.2以上版本中,SecureRandom获取方式发生了改变
if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
// 256 bits or 128 bits,192bits
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
/**
* 生成密钥 <br>
* Java 6 只支持56bit密钥 <br>
* Bouncy Castle 支持64bit密钥 <br>
*
* @return byte[] 二进制密钥
*
* @throws Exception
*/
public static byte[] initKey() throws NoSuchAlgorithmException {
/*
实例化密钥生成器
若要使用64bit密钥注意替换 将下述代码中的KeyGenerator.getInstance(CIPHER_ALGORITHM);
替换为KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");
*/
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
/*初始化密钥生成器 若要使用64bit密钥注意替换 将下述代码kg.init(56); 替换为kg.init(64);*/
kg.init(56, new SecureRandom());
// 生成秘密密钥
SecretKey secretKey = kg.generateKey();
// 获得密钥的二进制编码形式
return secretKey.getEncoded();
}
/**
* 生成加密秘钥
*
* @return
*/
private static SecretKeySpec getSecretKey(final String password) throws NoSuchAlgorithmException {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
// javax.crypto.BadPaddingException: Given final block not properly padded解决方案
// https://www.cnblogs.com/zempty/p/4318902.html - 用此法解决的
// https://www.cnblogs.com/digdeep/p/5580244.html - 留作参考吧
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(password.getBytes());
//AES 要求密钥长度为 128
kg.init(128, random);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
// 转换为AES专用密钥
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
}
/**
* Initialize IV, IV with offset, plain text, AAD and SecretKey
*
* @param keyLength length of a secret key
* @param tagLength tag length
* @param IVlength IV length
* @param offset offset in a buffer for IV
* @param textLength plain text length
* @param AADLength AAD length
*/
public GCMParameterSpecTest(int keyLength, int tagLength, int IVlength,
int offset, int textLength, int AADLength)
throws NoSuchAlgorithmException, NoSuchProviderException {
this.tagLength = tagLength; // save tag length
this.IVlength = IVlength; // save IV length
this.offset = offset; // save IV offset
// prepare IV
IV = Helper.generateBytes(IVlength);
// prepare IV with offset
IVO = new byte[this.IVlength + this.offset];
System.arraycopy(IV, 0, IVO, offset, this.IVlength);
// prepare data
data = Helper.generateBytes(textLength);
// prepare AAD
AAD = Helper.generateBytes(AADLength);
// init a secret key
KeyGenerator kg = KeyGenerator.getInstance("AES", "SunJCE");
kg.init(keyLength);
key = kg.generateKey();
}
@Override
public void create_key_if_not_available() throws KeyStoreException {
if (get(alias) == null) {
try {
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(KEY_LENGTH);
SecretKey key = kg.generateKey();
boolean success = put(getBytes(alias), key.getEncoded());
if (!success) {
throw new KeyStoreException("Keystore error");
}
} catch (Exception e) {
throw new KeyStoreException(e);
}
}
}
private static void doTest(String provider, String algo) throws Exception {
SecretKey key;
SecretKey keyToWrap;
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER);
kg.init(KEY_LENGTH);
key = kg.generateKey();
keyToWrap = kg.generateKey();
// initialization
Cipher cipher = Cipher.getInstance(algo, provider);
cipher.init(Cipher.WRAP_MODE, key);
AlgorithmParameters params = cipher.getParameters();
// wrap the key
byte[] keyWrapper = cipher.wrap(keyToWrap);
try {
// check if we can't wrap it again with the same key/IV
keyWrapper = cipher.wrap(keyToWrap);
throw new RuntimeException(
"FAILED: expected IllegalStateException hasn't "
+ "been thrown ");
} catch (IllegalStateException ise) {
System.out.println(ise.getMessage());
System.out.println("Expected exception");
}
// unwrap the key
cipher.init(Cipher.UNWRAP_MODE, key, params);
cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
// check if we can unwrap second time
Key unwrapKey = cipher.unwrap(keyWrapper, algo, Cipher.SECRET_KEY);
if (!Arrays.equals(keyToWrap.getEncoded(), unwrapKey.getEncoded())) {
throw new RuntimeException(
"FAILED: original and unwrapped keys are not equal");
}
}
/**
* 生成一个密钥
*
* @return 密钥的二进制形式
*/
public byte[] initKey() {
KeyGenerator kg = getKeyGenerator();
kg.init(getConfiguration().getKeySize());
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
/**
* @param provider Security provider
* @param algorithm Security algorithm to test
* @param mode The mode (GCM is only expected)
* @param padding Algorithm padding
* @param keyStrength key length
* @param textLength Plain text length
* @param AADLength Additional data length
*/
public Encrypt(Provider provider, String algorithm, String mode,
String padding, int keyStrength, int textLength, int AADLength)
throws Exception {
// init a secret Key
KeyGenerator kg = KeyGenerator.getInstance(algorithm, provider);
kg.init(keyStrength);
key = kg.generateKey();
this.provider = provider;
this.transformation = algorithm + "/" + mode + "/" + padding;
this.textLength = textLength;
this.AADLength = AADLength;
}
public static byte[] createBlob(String keyAlias, byte[] data, byte[] applicationId, long sid) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
keyGenerator.init(new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setCriticalToDeviceEncryption(true);
if (sid != 0) {
builder.setUserAuthenticationRequired(true)
.setBoundToSpecificSecureUserId(sid)
.setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY);
}
keyStore.setEntry(keyAlias,
new KeyStore.SecretKeyEntry(secretKey),
builder.build());
byte[] intermediate = encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, data);
return encrypt(secretKey, intermediate);
} catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
| InvalidKeyException e) {
e.printStackTrace();
throw new RuntimeException("Failed to encrypt blob", e);
}
}
/**
* 获取密钥
*
* @return
* @throws Exception
*/
public static Key getKey() throws Exception {
//实例化
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
//AES 要求密钥长度为128位、192位或256位
kg.init(KEY_SIZE);
//生成密钥
SecretKey secretKey = kg.generateKey();
return secretKey;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kGen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kGen.init(128, sr); // 192 and 256 bits may not be available
SecretKey sKey = kGen.generateKey();
return sKey.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");
}
}
/**
*
* AES CBC加密
*
* 数据块:128位
*
* @param strMsg
* : 需要加密的字符串
* @param sKey
* :加密key(16位)
* @param sKeyFormat
* :skey是否格式处理
* @param ivParameter
* :偏移量(16位)使用CBC模式,需要一个向量iv,可增加加密算法的强度
* @param encoding
* :编码
* @return :16进制的加密字符串
*/
public static String encryptByAesCBC(String strMsg, String sKey, boolean sKeyFormat, String ivParameter,
String encoding) {
try {
byte[] keyByte = null;
if (sKeyFormat) {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(sKey.getBytes()));
SecretKey secretKey = kgen.generateKey();
keyByte = secretKey.getEncoded();
}
else {
keyByte = sKey.getBytes(encoding);
}
SecretKeySpec skeySpec = new SecretKeySpec(keyByte, "AES");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 算法/模式/补码方式
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] resultByte = cipher.doFinal(strMsg.getBytes(encoding));
// 传输过程,转成16进制
String resultStr = parseByte2HexStr(resultByte);
return resultStr;
}
catch (Exception ex) {
ex.printStackTrace();
return "";
}
}
/**
* 生成密钥
* @return 密钥 byte[]
*/
public static byte[] initKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // 192 256
SecretKey secretKey = keyGen.generateKey();
return secretKey.getEncoded();
} catch (Exception e) {
JCLogUtils.eTag(TAG, e, "initKey");
}
return null;
}
private void wrapperBlowfishKeyTest() throws InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException,
IllegalBlockSizeException, InvalidAlgorithmParameterException {
// how many kinds of padding mode
int padKinds;
// Keysize should be multiple of 8 bytes.
int KeyCutter = 8;
int kSize = BLOWFISH_MIN_KEYSIZE;
String algorithm = "Blowfish";
int maxAllowKeyLength = Cipher.getMaxAllowedKeyLength(algorithm);
boolean unLimitPolicy = maxAllowKeyLength == Integer.MAX_VALUE;
SecretKey key = null;
while (kSize <= BLOWFISH_MAX_KEYSIZE) {
for (String mode : MODEL_AR) {
// PKCS5padding is meaningful only for ECB, CBC, PCBC
if (mode.equalsIgnoreCase(MODEL_AR[0])
|| mode.equalsIgnoreCase(MODEL_AR[1])
|| mode.equalsIgnoreCase(MODEL_AR[2])) {
padKinds = PADDING_AR.length;
} else {
padKinds = 1;
}
// Initialization
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
for (int k = 0; k < padKinds; k++) {
String transformation = algorithm + "/" + mode + "/"
+ PADDING_AR[k];
if (NOPADDING.equals(PADDING_AR[k]) && kSize % 64 != 0) {
out.println(transformation
+ " will not run if input length not multiple"
+ " of 8 bytes when padding is " + NOPADDING);
continue;
}
kg.init(kSize);
key = kg.generateKey();
// only run the tests on longer key lengths if unlimited
// version of JCE jurisdiction policy files are installed
if (!unLimitPolicy && kSize > LINIMITED_KEYSIZE) {
out.println("keyStrength > 128 within " + algorithm
+ " will not run under global policy");
} else {
wrapTest(transformation, transformation, key, key,
Cipher.SECRET_KEY, false);
}
}
}
if (kSize <= LINIMITED_KEYSIZE) {
KeyCutter = 8;
} else {
KeyCutter = 48;
}
kSize += KeyCutter;
}
}
/**
* 为密钥文件目录自动创建密钥, 只能从管理节点调用
* @param keyFileIni INI格式Key文件
*/
public static void createKeyFile(File keyFile) throws Exception
{
if ( keyFile.length()>0 ) {
logger.debug("Encryption key file "+keyFile+" exists, length "+keyFile.length());
return;
}
Base64.Encoder encoder = Base64.getEncoder();
KeyGenerator aesGen = KeyGenerator.getInstance("AES");
aesGen.init(256); // 192 and 256 bits may not be available
SecretKey aesKey = aesGen.generateKey();
KeyPairGenerator rsaGenerator = KeyPairGenerator.getInstance("RSA");
rsaGenerator.initialize(1024);
KeyPair keyPair = rsaGenerator.generateKeyPair();
PublicKey pub = keyPair.getPublic();
PrivateKey priv = keyPair.getPrivate();
String pubBase64 = encoder.encodeToString(pub.getEncoded());
SecureRandom random = new SecureRandom();
byte[] salt = new byte[20];
random.nextBytes(salt);
StringBuilder saltStr = new StringBuilder(128);
for(int i=0;i<salt.length;i++) {
if ( i>0 )
saltStr.append(",");
saltStr.append( Integer.toHexString( ((salt[i])&0XFF)) );
}
Cipher pbeCipher = getPBECipher(salt, Cipher.ENCRYPT_MODE);
String aesBase64 = encoder.encodeToString(pbeCipher.doFinal(aesKey.getEncoded()));
String privBase64 = encoder.encodeToString(pbeCipher.doFinal(priv.getEncoded()));
String aesId = "key_"+Base58.compressedUUID(UUID.randomUUID());
String rsaId = "key_"+Base58.compressedUUID(UUID.randomUUID());
IniWriter iniWrite = new IniWriter(FileUtil.bufferedWrite(keyFile));
iniWrite.writeSection("info");
iniWrite.writeProperty("aesId", aesId);
iniWrite.writeProperty("rsaId", rsaId);
iniWrite.writeProperty("createdTime", LocalDateTime.now());
iniWrite.writeProperty("publicFormat", pub.getFormat());
iniWrite.writeProperty("privateFormat", priv.getFormat());
iniWrite.writeProperty("salt", saltStr.toString());
iniWrite.writeSection("aes");
iniWrite.write(aesBase64);
iniWrite.writeSection("public");
iniWrite.write(pubBase64);
iniWrite.writeSection("private");
iniWrite.write(privBase64);
iniWrite.close();
logger.info("Create encryption file "+keyFile+" with key ids: "+aesId+", "+rsaId);
}
public static void main(String[] args) throws Exception {
Provider provider = Security.getProvider("SunJCE");
InputStream in = new FileInputStream(new File(BASE, "masterdata.txt"));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
int n = 0;
int lineNumber = 0;
String algorithm = null;
byte[] premaster = null;
byte[] clientRandom = null;
byte[] serverRandom = null;
int protoMajor = 0;
int protoMinor = 0;
int preMajor = 0;
int preMinor = 0;
byte[] master = null;
while (true) {
String line = reader.readLine();
lineNumber++;
if (line == null) {
break;
}
if (line.startsWith("m-") == false) {
continue;
}
String data = line.substring(PREFIX_LENGTH);
if (line.startsWith("m-algorithm:")) {
algorithm = data;
} else if (line.startsWith("m-premaster:")) {
premaster = parse(data);
} else if (line.startsWith("m-crandom:")) {
clientRandom = parse(data);
} else if (line.startsWith("m-srandom:")) {
serverRandom = parse(data);
} else if (line.startsWith("m-protomajor:")) {
protoMajor = Integer.parseInt(data);
} else if (line.startsWith("m-protominor:")) {
protoMinor = Integer.parseInt(data);
} else if (line.startsWith("m-premajor:")) {
preMajor = Integer.parseInt(data);
} else if (line.startsWith("m-preminor:")) {
preMinor = Integer.parseInt(data);
} else if (line.startsWith("m-master:")) {
master = parse(data);
System.out.print(".");
n++;
KeyGenerator kg =
KeyGenerator.getInstance("SunTlsMasterSecret", provider);
SecretKey premasterKey =
new SecretKeySpec(premaster, algorithm);
TlsMasterSecretParameterSpec spec =
new TlsMasterSecretParameterSpec(premasterKey, protoMajor,
protoMinor, clientRandom, serverRandom,
null, -1, -1);
kg.init(spec);
TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
byte[] enc = key.getEncoded();
if (Arrays.equals(master, enc) == false) {
throw new Exception("mismatch line: " + lineNumber);
}
if ((preMajor != key.getMajorVersion()) ||
(preMinor != key.getMinorVersion())) {
throw new Exception("version 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");
}
/**
* Initialize the private key for given algorithm+keySize once in the lifetime
* of distributed system.
*/
public static String initializePrivateKey(String algo, int keySize,
final LanguageConnectionContext lcc) throws Exception {
// create the private key used for symmetric encryption of user provided
// passwords and other secrets, if not created yet; this is done only
// once in the entire lifetime of a distributed system for a particular
// algorithm+keySize combination
final GemFireStore store = Misc.getMemStoreBooting();
if (algo == null) {
algo = GfxdConstants.PASSWORD_PRIVATE_KEY_ALGO_DEFAULT;
}
if (keySize <= 0) {
keySize = GfxdConstants.PASSWORD_PRIVATE_KEY_SIZE_DEFAULT;
}
final String secretProp = GemFireXDUtils.getPrivateKeyDBKey(algo, keySize);
String secret = PropertyUtil.getDatabaseProperty(store, secretProp);
if (secret == null) {
final GfxdDataDictionary dd = store.getDatabase().getDataDictionary();
// acquire DD write lock first
final TransactionController tc = lcc != null ? lcc
.getTransactionExecute() : null;
final boolean ddLocked = dd.lockForWriting(tc, false);
try {
// check again
secret = PropertyUtil.getDatabaseProperty(store, secretProp);
if (secret == null) {
// generate new private key
KeyGenerator gen = KeyGenerator.getInstance(algo);
gen.init(keySize);
byte[] key = gen.generateKey().getEncoded();
secret = ClientSharedUtils.toHexString(key, 0, key.length);
store.setProperty(secretProp, secret, false);
// lets publish this database property so that all JVMs see it
GfxdSystemProcedures.publishMessage(
new Object[] { secretProp, secret }, false,
GfxdSystemProcedureMessage.SysProcMethod.setDatabaseProperty,
true, true);
}
} finally {
if (ddLocked) {
dd.unlockAfterWriting(tc, false);
}
}
}
return secret;
}
/**
* Generate a new AES key used to encrypt the message.
*
* @param keyType Key Type
* @param keyLength Key Length in bit
* @return new AES key
*
* @throws NoSuchAlgorithmException if no such algorithm is available.
*/
public static byte[] generateKey(String keyType, int keyLength) throws NoSuchAlgorithmException {
KeyGenerator generator = KeyGenerator.getInstance(keyType);
generator.init(keyLength);
return generator.generateKey().getEncoded();
}