use of javax.crypto.spec.GCMParameterSpec in project wycheproof by google.
the class JsonAeadTest method getInitializedCipher.
/**
* Returns an initialized instance of Cipher. Typically it is somewhat
* time consuming to generate a new instance of Cipher for each encryption.
* However, some implementations of ciphers (e.g. AES-GCM in jdk) check that
* the same key and nonce are not reused twice in a row to catch simple
* programming errors. This precaution can interfere with the tests, since
* the test vectors do sometimes repeat nonces. To avoid such problems cipher
* instances are not reused.
* @param algorithm the cipher algorithm including encryption mode and padding.
* @param opmode one of Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE
* @param key the key bytes
* @param iv the bytes of the initialization vector
* @param tagSize the expected size of the tag
* @return an initialized instance of Cipher
* @throws Exception if the initialization failed.
*/
protected static Cipher getInitializedCipher(String algorithm, int opmode, byte[] key, byte[] iv, int tagSize) throws Exception {
Cipher cipher = Cipher.getInstance(algorithm);
if (algorithm.equalsIgnoreCase("AES/GCM/NoPadding")) {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
GCMParameterSpec parameters = new GCMParameterSpec(tagSize, iv);
cipher.init(opmode, keySpec, parameters);
} else if (algorithm.equalsIgnoreCase("AES/EAX/NoPadding") || algorithm.equalsIgnoreCase("AES/CCM/NoPadding")) {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
// TODO(bleichen): This works for BouncyCastle but looks non-standard.
// org.bouncycastle.crypto.params.AEADParameters works too, but would add a dependency that
// we want to avoid.
GCMParameterSpec parameters = new GCMParameterSpec(tagSize, iv);
cipher.init(opmode, keySpec, parameters);
} else if (algorithm.toUpperCase().startsWith("CHACHA")) {
SecretKeySpec keySpec = new SecretKeySpec(key, "ChaCha20");
IvParameterSpec parameters = new IvParameterSpec(iv);
cipher.init(opmode, keySpec, parameters);
} else {
fail("Algorithm not supported:" + algorithm);
}
return cipher;
}
use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.
the class SQRLStorage method encryptRescueKey.
/**
* Encrypt the identity key, this has the master key used to login to sites and also the lock
* key that we supply to the sites in order to lock at a later date if the master key ever
* gets compromised.
*
* @param entropyHarvester Class to give us new random bits for encryption
*/
public boolean encryptRescueKey(EntropyHarvester entropyHarvester) {
this.progressionUpdater.clear();
this.rescueRandomSalt = new byte[16];
this.rescueLogNFactor = 9;
this.rescueIdentityUnlockKey = new byte[32];
this.rescueIdentityUnlockKeyEncrypted = new byte[32];
this.rescueVerificationTag = new byte[16];
this.hasRescueBlock = true;
// 2 min 30 seconds.
byte rescueCodeEncryptionTime = (byte) 150;
try {
entropyHarvester.fetchRandom(this.rescueRandomSalt);
entropyHarvester.fetchRandom(this.rescueIdentityUnlockKey);
byte[] encResult = EncryptionUtils.enSCryptTime(getTempRescueCode(), rescueRandomSalt, rescueLogNFactor, 32, rescueCodeEncryptionTime, this.progressionUpdater);
this.rescueIterationCount = getIntFromFourBytes(encResult, 0);
byte[] key = Arrays.copyOfRange(encResult, 4, 36);
byte[] nullBytes = new byte[12];
Arrays.fill(nullBytes, (byte) 0);
this.updateRescuePlaintext();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Key keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, params);
cipher.updateAAD(rescuePlaintext);
cipher.update(rescueIdentityUnlockKey);
byte[] encryptionResult = cipher.doFinal();
this.rescueIdentityUnlockKeyEncrypted = Arrays.copyOfRange(encryptionResult, 0, 32);
this.rescueVerificationTag = Arrays.copyOfRange(encryptionResult, 32, 48);
} else {
byte[] resultVerificationTag = new byte[16];
byte[] encryptionResult = new byte[rescueIdentityUnlockKey.length];
Grc_aesgcm.gcm_setkey(key, key.length);
int res = Grc_aesgcm.gcm_encrypt_and_tag(nullBytes, nullBytes.length, rescuePlaintext, rescuePlaintext.length, rescueIdentityUnlockKey, encryptionResult, rescueIdentityUnlockKey.length, resultVerificationTag, resultVerificationTag.length);
Grc_aesgcm.gcm_zero_ctx();
if (res == 0x55555555)
return false;
this.rescueIdentityUnlockKeyEncrypted = encryptionResult;
this.rescueVerificationTag = resultVerificationTag;
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
return false;
}
return true;
}
use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.
the class SQRLStorage method encryptIdentityKeyQuickPass.
/**
* Encrypt the identity key, this has the master key used to login to sites and also the lock
* key that we supply to the sites in order to lock at a later date if the master key ever
* gets compromised.
*
* @param password Password used to encrypt the master key.
* @param entropyHarvester Class to give us new random bits for encryption
*/
public boolean encryptIdentityKeyQuickPass(String password, EntropyHarvester entropyHarvester) {
if (!this.hasKeys() || !this.hasEncryptedKeys())
return false;
this.progressionUpdater.clear();
password = password.substring(0, this.getHintLength());
this.quickPassRandomSalt = new byte[16];
this.quickPassInitializationVector = new byte[12];
this.quickPassKeyEncrypted = new byte[32];
this.quickPassVerificationTag = new byte[16];
try {
entropyHarvester.fetchRandom(this.quickPassRandomSalt);
byte[] encResult = EncryptionUtils.enSCryptTime(password, this.quickPassRandomSalt, logNFactor, 32, timeInSecondsToRunPWEnScryptOnPassword, this.progressionUpdater);
this.quickPassIterationCount = getIntFromFourBytes(encResult, 0);
byte[] key = Arrays.copyOfRange(encResult, 4, 36);
entropyHarvester.fetchRandom(this.quickPassInitializationVector);
this.updateIdentityPlaintext();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Key keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, this.quickPassInitializationVector);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, params);
cipher.update(identityMasterKey);
byte[] encryptionResult = cipher.doFinal();
this.quickPassKeyEncrypted = Arrays.copyOfRange(encryptionResult, 0, 32);
this.quickPassVerificationTag = Arrays.copyOfRange(encryptionResult, 32, 48);
} else {
byte[] emptyPlainText = new byte[0];
Grc_aesgcm.gcm_setkey(key, key.length);
int res = Grc_aesgcm.gcm_encrypt_and_tag(this.quickPassInitializationVector, this.quickPassInitializationVector.length, emptyPlainText, emptyPlainText.length, identityMasterKey, this.quickPassKeyEncrypted, identityMasterKey.length, this.quickPassVerificationTag, this.quickPassVerificationTag.length);
Grc_aesgcm.gcm_zero_ctx();
if (res == 0x55555555)
return false;
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
return false;
}
return true;
}
use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.
the class SQRLStorage method decryptUnlockKey.
/**
* This unlocks the unlock key used to recover your identity if your master key gets comprimised
* this key should NEVER be saved in the device. It's just used to create a new identity.
*
* @param rescueCode Special rescueCode printed on paper in the format of 0000-0000-0000-0000-0000-0000
*/
public boolean decryptUnlockKey(String rescueCode) {
this.progressionUpdater.setMax(rescueIterationCount);
rescueCode = rescueCode.replaceAll("-", "");
try {
byte[] key = EncryptionUtils.enSCryptIterations(rescueCode, rescueRandomSalt, rescueLogNFactor, 32, rescueIterationCount, this.progressionUpdater);
byte[] nullBytes = new byte[12];
Arrays.fill(nullBytes, (byte) 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Key keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
cipher.updateAAD(rescuePlaintext);
cipher.update(rescueIdentityUnlockKeyEncrypted);
try {
rescueIdentityUnlockKey = cipher.doFinal(rescueVerificationTag);
} catch (AEADBadTagException badTag) {
return false;
}
} else {
rescueIdentityUnlockKey = new byte[rescueIdentityUnlockKeyEncrypted.length];
Grc_aesgcm.gcm_setkey(key, key.length);
int res = Grc_aesgcm.gcm_auth_decrypt(nullBytes, nullBytes.length, rescuePlaintext, rescuePlaintext.length, rescueIdentityUnlockKeyEncrypted, rescueIdentityUnlockKey, rescueIdentityUnlockKeyEncrypted.length, rescueVerificationTag, rescueVerificationTag.length);
Grc_aesgcm.gcm_zero_ctx();
if (res == 0x55555555)
return false;
}
} catch (Exception e) {
Log.e(SQRLStorage.TAG, e.getMessage(), e);
return false;
}
return true;
}
use of javax.crypto.spec.GCMParameterSpec in project secure-quick-reliable-login by kalaspuffar.
the class SQRLStorage method decryptPreviousBlock.
private boolean decryptPreviousBlock() {
try {
byte[] identityKeys = previousKey1Encrypted;
if (previousCountOfKeys > 1) {
identityKeys = EncryptionUtils.combine(identityKeys, previousKey2Encrypted);
}
if (previousCountOfKeys > 2) {
identityKeys = EncryptionUtils.combine(identityKeys, previousKey3Encrypted);
}
if (previousCountOfKeys > 3) {
identityKeys = EncryptionUtils.combine(identityKeys, previousKey4Encrypted);
}
byte[] decryptionResult = new byte[identityKeys.length];
byte[] nullBytes = new byte[12];
Arrays.fill(nullBytes, (byte) 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Key keySpec = new SecretKeySpec(this.identityMasterKey, "AES");
Cipher cipher = Cipher.getInstance("AES_256/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, nullBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
cipher.updateAAD(previousPlaintext);
cipher.update(identityKeys);
try {
decryptionResult = cipher.doFinal(previousVerificationTag);
} catch (AEADBadTagException badTag) {
return false;
}
} else {
Grc_aesgcm.gcm_setkey(this.identityMasterKey, identityMasterKey.length);
int res = Grc_aesgcm.gcm_auth_decrypt(nullBytes, nullBytes.length, previousPlaintext, previousPlaintext.length, identityKeys, decryptionResult, identityKeys.length, previousVerificationTag, previousVerificationTag.length);
Grc_aesgcm.gcm_zero_ctx();
if (res == 0x55555555)
return false;
}
previousKey1 = Arrays.copyOfRange(decryptionResult, 0, 32);
if (previousCountOfKeys > 1) {
previousKey2 = Arrays.copyOfRange(decryptionResult, 32, 64);
}
if (previousCountOfKeys > 2) {
previousKey3 = Arrays.copyOfRange(decryptionResult, 64, 96);
}
if (previousCountOfKeys > 3) {
previousKey4 = Arrays.copyOfRange(decryptionResult, 96, 128);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
return false;
}
return true;
}
Aggregations