下面列出了java.security.spec.InvalidParameterSpecException#javax.crypto.IllegalBlockSizeException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static String encrypt(String value) {
try {
System.out.println(KEY);
DESKeySpec keySpec = new DESKeySpec(KEY);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
byte[] clearText = value.getBytes("UTF8");
// Implement this in a thread safe way, or switch to AES.
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
String encrypedText = Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT);
Log.d("Oh snap!", "Encrypted: " + value + " -> " + encrypedText);
return encrypedText;
} catch (InvalidKeyException | UnsupportedEncodingException | InvalidKeySpecException | NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException e) {
e.printStackTrace();
}
return value;
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* <p>
* The <code>close</code> method of <code>CipherInputStream</code>
* calls the <code>close</code> method of its underlying input
* stream.
*
* @exception IOException if an I/O error occurs.
* @since JCE1.2
*/
public void close() throws IOException {
if (closed) {
return;
}
closed = true;
input.close();
// Throw away the unprocessed data and throw no crypto exceptions.
// AEAD ciphers are fully readed before closing. Any authentication
// exceptions would occur while reading.
if (!done) {
try {
cipher.doFinal();
}
catch (BadPaddingException | IllegalBlockSizeException ex) {
// Catch exceptions as the rest of the stream is unused.
}
}
ostart = 0;
ofinish = 0;
}
public JsonNode login(String user, String password)
throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException {
String authParameters = encryptAuthParameter(user, password);
// Send login request
Response response =
baseResource
.path("login")
.queryParam("service", Main.SERVICE)
.queryParam("auth", authParameters)
.request(responseType)
.post(null);
ObjectNode json = response.readEntity(ObjectNode.class);
JsonNode node = new ObjectMapper().readTree(json.toString());
String sessionKey = json.get("session_key").asText();
// Add the session key to basic auth for all calls
baseResource.register(HttpAuthenticationFeature.basic(sessionKey, sessionKey));
return node;
}
public static void main(String[] args) throws ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
byte[] plainText = new byte[801];
// Initialization
RandomFactory.getRandom().nextBytes(plainText);
Cipher ci = new NullCipher();
// Encryption
byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
int offset = ci.update(plainText, 0, plainText.length, cipherText, 0);
ci.doFinal(cipherText, offset);
// Decryption
byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
int len = ci.doFinal(cipherText, 0, cipherText.length, recoveredText);
// Comparison
if (len != plainText.length ||
!TestUtilities.equalsBlock(plainText, cipherText, len) ||
!TestUtilities.equalsBlock(plainText, recoveredText, len)) {
throw new RuntimeException(
"Test failed because plainText not equal to cipherText and revoveredText");
}
}
/**
* Wrap a key.
*
* @param key the key to be wrapped.
*
* @return the wrapped key.
*
* @exception IllegalBlockSizeException if this cipher is a block
* cipher, no padding has been requested, and the length of the
* encoding of the key to be wrapped is not a
* multiple of the block size.
*
* @exception InvalidKeyException if it is impossible or unsafe to
* wrap the key with this cipher (e.g., a hardware protected key is
* being passed to a software only cipher).
*/
protected final byte[] engineWrap(Key key)
throws IllegalBlockSizeException, InvalidKeyException
{
byte[] result = null;
try {
byte[] encodedKey = key.getEncoded();
if ((encodedKey == null) || (encodedKey.length == 0)) {
throw new InvalidKeyException("Cannot get an encoding of " +
"the key to be wrapped");
}
result = engineDoFinal(encodedKey, 0, encodedKey.length);
} catch (BadPaddingException e) {
// Should never happen
}
return result;
}
public String decrypt(String encrypted) throws DecryptionException {
if (encrypted == null || encrypted.isEmpty()) {
loggerGER.warning("Skipped empty decryption try.");
return encrypted;
}
try {
byte[] crypted2 = base64Decode(encrypted);
Cipher cipher = Cipher.getInstance(CRYPT_METHOD);
cipher.init(Cipher.DECRYPT_MODE, PRIVATE_KEY);
byte[] cipherData2 = cipher.doFinal(crypted2);
return new String(cipherData2);
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException e) {
throw new DecryptionException(e);
}
}
public byte[] decryptWithSymmetricKey(byte[] encryptionBytes) throws CryptoException {
Cipher c = null;
byte[] decryptedData = null;
String encryptionAlgo;
try {
if (symmetricKeyEncryptAlgo == null) {
encryptionAlgo = symmetricKeyEncryptAlgoDefault;
} else {
encryptionAlgo = symmetricKeyEncryptAlgo;
}
c = Cipher.getInstance(encryptionAlgo);
c.init(Cipher.DECRYPT_MODE, symmetricKey);
decryptedData = c.doFinal(encryptionBytes);
} catch (InvalidKeyException | BadPaddingException | IllegalBlockSizeException |
NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new CryptoException("Error when decrypting data.", e);
}
return decryptedData;
}
public static byte[] encrypt(byte[] data, String key)
throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
MessageDigest digest = MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM);
digest.update(key.getBytes("UTF-8"));
// default JVM impl. may only support key strength up to 128 bit;
byte[] keyData = new byte[16];
System.arraycopy(digest.digest(), 0, keyData, 0, keyData.length);
SecretKeySpec keySpec = new SecretKeySpec(keyData, SECRET_KEY_ALGORITHM);
IvParameterSpec ivSpec = new IvParameterSpec(IV);
data = deflate(data);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
return xor(cipher.doFinal(data));
}
/**
* Obfuscate a password.
*
* @param password The password as a String.
*
* @return The obfuscated password.
*/
public static ObfuscatedPassword obfuscate(final String password) {
final IvParameterSpec iv = new IvParameterSpec(PasswordUtilities.getIV());
final SecretKey key = new SecretKeySpec(PasswordUtilities.getKey(), PasswordUtilities.ALG);
try {
final Cipher cipher = Cipher.getInstance(PasswordUtilities.ALG_SPEC);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] encrypted = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
final StringBuilder encryptedHex = new StringBuilder();
for (final byte b : encrypted) {
encryptedHex.append(String.format("%02x", b));
}
return new ObfuscatedPassword(encryptedHex.toString());
} catch (final InvalidKeyException | IllegalBlockSizeException | BadPaddingException
| NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException ex) {
throw new RuntimeException(ex);
}
}
private static void decrypt(byte[] encryptedBytes, ByteArrayOutputStream baos, int index, int blockSize, ConnectorCryptoUtils.Decryptor decryptor) throws IOException, IllegalBlockSizeException, BadPaddingException {
if (blockSize == 0) {
baos.write(decryptor.doFinal(encryptedBytes, 0, encryptedBytes.length));
} else {
for(; index < encryptedBytes.length; index += blockSize) {
if (index + blockSize >= encryptedBytes.length) {
baos.write(decryptor.doFinal(encryptedBytes, index, blockSize));
} else {
byte[] blockResult = decryptor.update(encryptedBytes, index, blockSize);
if (blockResult != null) {
baos.write(blockResult);
}
}
}
}
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
*
* @return byte[] 解密数据
*
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
// 还原密钥
Key k = toKey(key);
/*
* 实例化 使用PKCS7Padding填充方式 Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* This method encrypts the plaintext with a data key stored AWS Secret Manager. Before using this function, create
* a secret in AWS Secret Manager. Do a base64 encode to your data key and convert it to string. Store it as
* _PLAINTEXT_ in the secret (do not include any quotes, brackets, etc). Also make sure to use DefaultEncryptionKey
* as the KMS key. Otherwise you would need to update athena-udfs.yaml to allow access to your KMS key.
*
* @param plaintext
* @param secretName
* @return ciphertext
*/
public String encrypt(String plaintext, String secretName)
{
String secretString = cachableSecretsManager.getSecret(secretName);
byte[] plaintextKey = Base64.getDecoder().decode(secretString);
try {
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE, plaintextKey);
byte[] encryptedContent = cipher.doFinal(plaintext.getBytes());
byte[] encodedContent = Base64.getEncoder().encode(encryptedContent);
return new String(encodedContent);
}
catch (IllegalBlockSizeException | BadPaddingException e) {
throw new RuntimeException(e);
}
}
/**
* 解密
*
* @param data
* 数据
* @param password
* 密码
* @param salt
* 盐
*
* @return byte[] 解密数据
*
* @throws Exception
*/
public static byte[] decrypt(byte[] data, String password, byte[] salt) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// 转换密钥
Key key = toKey(password);
// 实例化PBE参数材料
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
// 实例化
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化
cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
// 执行操作
return cipher.doFinal(data);
}
@Test
public void encrypt_shouldEncryptTheStringWithoutAttemptingToReconnect() throws Exception {
when(keySet.getActive())
.thenReturn(firstActiveKey);
final EncryptedValue expectedEncryption = mock(EncryptedValue.class);
when(firstActiveKey.encrypt("fake-plaintext"))
.thenReturn(expectedEncryption);
final EncryptedValue encryptedValue = subject.encrypt("fake-plaintext");
assertThat(encryptedValue, equalTo(expectedEncryption));
verify(encryptionService, times(0))
.reconnect(any(IllegalBlockSizeException.class));
verify(keySet, times(0)).reload();
}
private void wrapperPublicPriviteKeyTest(Provider p, String[] algorithms)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, IllegalBlockSizeException,
InvalidAlgorithmParameterException {
for (String algo : algorithms) {
// Key pair generated
System.out.println("Generate key pair (algorithm: " + algo
+ ", provider: " + p.getName() + ")");
KeyPairGenerator kpg = KeyPairGenerator.getInstance(algo);
kpg.initialize(512);
KeyPair kp = kpg.genKeyPair();
// key generated
String algoWrap = "DES";
KeyGenerator kg = KeyGenerator.getInstance(algoWrap, p);
Key key = kg.generateKey();
wrapTest(algo, algoWrap, key, kp.getPrivate(), Cipher.PRIVATE_KEY,
false);
wrapTest(algo, algoWrap, key, kp.getPublic(), Cipher.PUBLIC_KEY,
false);
}
}
private void wrapperPBEKeyTest(Provider p) throws InvalidKeySpecException,
InvalidKeyException, NoSuchPaddingException,
IllegalBlockSizeException, InvalidAlgorithmParameterException,
NoSuchAlgorithmException {
for (String alg : PBE_ALGORITHM_AR) {
String baseAlgo = alg.split("/")[0].toUpperCase();
// only run the tests on longer key lengths if unlimited version
// of JCE jurisdiction policy files are installed
if (Cipher.getMaxAllowedKeyLength(alg) < Integer.MAX_VALUE
&& (baseAlgo.endsWith("TRIPLEDES") || alg
.endsWith("AES_256"))) {
out.println("keyStrength > 128 within " + alg
+ " will not run under global policy");
continue;
}
SecretKeyFactory skf = SecretKeyFactory.getInstance(baseAlgo, p);
SecretKey key = skf.generateSecret(new PBEKeySpec("Secret Lover"
.toCharArray()));
wrapTest(alg, alg, key, key, Cipher.SECRET_KEY, true);
}
}
public static String getEncrypted(String plainText) {
Cipher cipher = null;
byte[] encryptedTextBytes = null;
try {
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new CustomKey());
encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e1) {
e1.printStackTrace();
}
return DatatypeConverter.printBase64Binary(encryptedTextBytes);
}
/**
* AES解密
*
* @param data 密文,被加密的数据
* @param key 秘钥
* @param iv 偏移量
* @param encodingFormat 解密后的结果需要进行的编码
*/
public static String decrypt(
final String data, final String key, final String iv, final Charset encodingFormat) {
// 被加密的数据
final byte[] dataByte = Base64.decodeBase64(data);
// 加密秘钥
final byte[] keyByte = Base64.decodeBase64(key);
// 偏移量
final byte[] ivByte = Base64.decodeBase64(iv);
try {
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
final SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
final AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
final byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
return new String(resultByte, encodingFormat);
}
return null;
} catch (final NoSuchAlgorithmException
| NoSuchPaddingException
| InvalidParameterSpecException
| InvalidKeyException
| InvalidAlgorithmParameterException
| IllegalBlockSizeException
| BadPaddingException
| NoSuchProviderException e) {
e.printStackTrace();
}
return null;
}
@Test
public void mapUuidsToKeys_whenTheActiveKeyIsTheOnlyKey_whenThereIsNoMatchingCanaryInTheDatabase_whenDecryptingWithTheWrongKeyRaisesAnHSMException_itShouldCreateACanaryForTheKey()
throws Exception {
when(encryptionKeysConfiguration.isKeyCreationEnabled()).thenReturn(true);
when(encryptionKeysConfiguration.getProviders().get(0).getKeys()).thenReturn(asList(activeKeyData));
when(encryptionKeysConfiguration.getProviders()).thenReturn(asList(activeProvider));
final EncryptionKeyCanary nonMatchingCanary = new EncryptionKeyCanary();
nonMatchingCanary.setUuid(UUID.randomUUID());
nonMatchingCanary.setEncryptedCanaryValue("fake-non-matching-encrypted-value".getBytes(UTF_8));
nonMatchingCanary.setNonce("fake-non-matching-nonce".getBytes(UTF_8));
when(encryptionKeyCanaryDataService.findAll())
.thenReturn(asArrayList(nonMatchingCanary));
when(encryptionService
.decrypt(activeKey, nonMatchingCanary.getEncryptedCanaryValue(),
nonMatchingCanary.getNonce()))
.thenThrow(new IllegalBlockSizeException(
"Could not process input data: function 'C_Decrypt' returns 0x40"));
when(encryptionKeyCanaryDataService.save(any(EncryptionKeyCanary.class)))
.thenReturn(activeKeyCanary);
when(encryptionService.encrypt(any(EncryptionKey.class), eq(CANARY_VALUE))).thenReturn(new EncryptedValue(
null,
"fake-encrypted-value",
"fake-nonce"));
subject = new EncryptionKeyCanaryMapper(encryptionKeyCanaryDataService,
encryptionKeysConfiguration, timedRetry, providerFactory);
subject.mapUuidsToKeys(keySet);
assertCanaryValueWasEncryptedAndSavedToDatabase();
}
public static byte[] deriveAccessKeyFrom(ProfileKey profileKey) {
try {
byte[] nonce = new byte[12];
byte[] input = new byte[16];
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(profileKey.serialize(), "AES"), new GCMParameterSpec(128, nonce));
byte[] ciphertext = cipher.doFinal(input);
return ByteUtil.trim(ciphertext, 16);
} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException | BadPaddingException | IllegalBlockSizeException e) {
throw new AssertionError(e);
}
}
@Test
public final void test256bitKey()
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
SecureRandom sr = SecureRandom.getInstanceStrong();
byte[] nonce = new byte[16];
sr.nextBytes(nonce);
KeyGenerator keygen = KeyGenerator.getInstance("AES");
keygen.init(256);
byte[] key = keygen.generateKey().getEncoded();
byte[] data = new byte[256];
sr.nextBytes(data);
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
GCMParameterSpec paramSpec = new GCMParameterSpec(128, nonce);
try {
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), paramSpec);
cipher.doFinal(data);
} catch (InvalidKeyException e) {
throw new InterledgerRuntimeException("Error loading 256bit key. "
+ "Likley cause is missing Unlimited Strength Jurisdiction Policy Files.", e);
}
}
protected byte[] engineDoFinal(
byte[] input,
int inputOffset,
int inputLen)
throws IllegalBlockSizeException, BadPaddingException
{
int len = 0;
byte[] tmp = new byte[engineGetOutputSize(inputLen)];
if (inputLen != 0)
{
len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0);
}
try
{
len += cipher.doFinal(tmp, len);
}
catch (DataLengthException e)
{
throw new IllegalBlockSizeException(e.getMessage());
}
if (len == tmp.length)
{
return tmp;
}
byte[] out = new byte[len];
System.arraycopy(tmp, 0, out, 0, len);
return out;
}
/**
* Computes and returns the cleartext of the given ciphertext.
*
* @param ciphertext The ciphertext to be decrypted.
* @param algorithm The encryption / decryption algorithm
* @param javaSecurityAPIProvider
* @return The cleartext
* @throws CryptoException If something unexpected happens during the decryption operation.
*/
public byte[] decrypt(byte[] ciphertext, String algorithm, String javaSecurityAPIProvider) throws CryptoException {
try {
Cipher cipher;
if (StringUtils.isBlank(javaSecurityAPIProvider)) {
cipher = Cipher.getInstance(algorithm);
} else {
cipher = Cipher.getInstance(algorithm, javaSecurityAPIProvider);
}
cipher.init(Cipher.DECRYPT_MODE, getPrivateKeyFromKeyStore());
if (log.isDebugEnabled()) {
log.debug(String.format("Successfully decrypted data using the algorithm '%s' and the "
+ "Java Security API provider '%s'", algorithm,
javaSecurityAPIProvider));
}
return cipher.doFinal(ciphertext);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | UnrecoverableKeyException | KeyStoreException e) {
String errorMessage = String
.format("An error occurred while decrypting using the algorithm : '%s'", algorithm);
// Log the exception from client libraries, to avoid missing information if callers code doesn't log it
if (log.isDebugEnabled()) {
log.debug(errorMessage, e);
}
throw new CryptoException(errorMessage, e);
}
}
protected byte[] encryptSymmetricKey(byte[] keyBytes,
X509Certificate remoteCert,
String keyEncAlgo,
String digestAlgo) throws WSSecurityException {
Cipher cipher =
EncryptionUtils.initCipherWithCert(
keyEncAlgo, digestAlgo, Cipher.ENCRYPT_MODE, remoteCert
);
int blockSize = cipher.getBlockSize();
if (blockSize > 0 && blockSize < keyBytes.length) {
String message = "Public key algorithm too weak to encrypt symmetric key";
LOG.severe(message);
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILURE,
"unsupportedKeyTransp",
new Object[] {message}
);
}
byte[] encryptedEphemeralKey = null;
try {
encryptedEphemeralKey = cipher.doFinal(keyBytes);
} catch (IllegalStateException | IllegalBlockSizeException | BadPaddingException ex) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, ex
);
}
return encryptedEphemeralKey;
}
/** {@inheritDoc} */
@Override public byte[] encrypt(byte[] data) {
if (data == null)
throw new IgniteException("Parameter [data] cannot be null");
if (encCipher == null)
throw new IgniteException("The init() method was not called.");
try {
return encCipher.doFinal(data);
}
catch (IllegalBlockSizeException | BadPaddingException e) {
throw new IgniteException(e);
}
}
/**
* The private key corresponding to the contract certificate is to be decrypted by
* the receiver (EVCC) using the session key derived in the ECDH protocol.
* Applies the algorithm AES-CBC-128 according to NIST Special Publication 800-38A.
* The initialization vector IV shall be read from the 16 most significant bytes of the
* ContractSignatureEncryptedPrivateKey field.
*
* @param sessionKey The symmetric session key with which the encrypted private key is to be decrypted
* @param encryptedKeyWithIV The encrypted private key of the contract certificate given as a byte array
* whose first 16 byte hold the initialization vector
* @return The decrypted private key of the contract certificate
*/
private static ECPrivateKey decryptPrivateKey(SecretKey sessionKey, byte[] encryptedKeyWithIV) {
byte[] initVector = new byte[16];
byte[] encryptedKey = null;
try {
// Get the first 16 bytes of the encrypted private key which hold the IV
encryptedKey = new byte[encryptedKeyWithIV.length - 16];
System.arraycopy(encryptedKeyWithIV, 0, initVector, 0, 16);
System.arraycopy(encryptedKeyWithIV, 16, encryptedKey, 0, encryptedKeyWithIV.length - 16);
IvParameterSpec ivParamSpec = new IvParameterSpec(initVector);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
/*
* You must have the Java Cryptography Extension (JCE) Unlimited Strength
* Jurisdiction Policy Files 8 installed, otherwise this cipher.init call will yield a
* "java.security.InvalidKeyException: Illegal key size"
*/
cipher.init(Cipher.DECRYPT_MODE, sessionKey, ivParamSpec);
byte[] decrypted = cipher.doFinal(encryptedKey);
return getPrivateKey(decrypted);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException |
NegativeArraySizeException e) {
getLogger().error(e.getClass().getSimpleName() + " occurred while trying to decrypt private key" +
"\nSession key (" + (sessionKey != null ? sessionKey.getEncoded().length : 0) + " bytes): " +
ByteUtils.toHexString(sessionKey.getEncoded()) +
"\nEncrypted key (" + (encryptedKey != null ? encryptedKey.length : 0) + " bytes): " +
ByteUtils.toHexString(encryptedKey) +
"\nEncrypted key with IV (" + (encryptedKeyWithIV != null ? encryptedKeyWithIV.length : 0) + " bytes): " +
ByteUtils.toHexString(encryptedKey), e);
}
return null;
}
public void reset(InputStream in) throws IOException
{
this.in = in;
this.inBufPos = 16;
this.end = false;
try
{
this.cipher.doFinal(cipherBuf, 0, 0, inBuf);
}
catch (ShortBufferException | IllegalBlockSizeException | BadPaddingException e)
{
throw new IOException(e);
}
}
public XmppAxolotlPlaintextMessage decrypt(XmppAxolotlSession session, Integer sourceDeviceId) throws CryptoFailedException {
XmppAxolotlPlaintextMessage plaintextMessage = null;
byte[] key = unpackKey(session, sourceDeviceId);
if (key != null) {
try {
if (key.length < 32) {
throw new OutdatedSenderException("Key did not contain auth tag. Sender needs to update their OMEMO client");
}
final int authTagLength = key.length - 16;
byte[] newCipherText = new byte[key.length - 16 + ciphertext.length];
byte[] newKey = new byte[16];
System.arraycopy(ciphertext, 0, newCipherText, 0, ciphertext.length);
System.arraycopy(key, 16, newCipherText, ciphertext.length, authTagLength);
System.arraycopy(key, 0, newKey, 0, newKey.length);
ciphertext = newCipherText;
key = newKey;
final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE);
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
String plaintext = new String(cipher.doFinal(ciphertext));
plaintextMessage = new XmppAxolotlPlaintextMessage(Config.OMEMO_PADDING ? plaintext.trim() : plaintext, session.getFingerprint());
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| InvalidAlgorithmParameterException | IllegalBlockSizeException
| BadPaddingException | NoSuchProviderException e) {
throw new CryptoFailedException(e);
}
}
return plaintextMessage;
}
static void cbc_readAllIllegalBlockSize() throws Exception {
byte[] read = new byte[200];
System.out.println("Running cbc_readAllIllegalBlockSize test");
// Encrypt 96 byte with AES/CBC/PKCS5Padding
byte[] ct = encryptedText("CBC", 96);
// Create a stream with only 95 bytes of encrypted data
CipherInputStream in = getStream("CBC", ct, 95);
try {
int s, size = 0;
while ((s = in.read(read)) != -1) {
size += s;
}
throw new RuntimeException("Fail: No IllegalBlockSizeException. " +
"CipherInputStream.read() returned " + size);
} catch (IOException e) {
Throwable ec = e.getCause();
if (ec instanceof IllegalBlockSizeException) {
System.out.println(" Pass.");
} else {
System.out.println(" Fail: " + ec.getMessage());
throw new RuntimeException(ec);
}
}
}
@Override
public String decrypt(String encryptedString) throws GeneralSecurityException {
try {
if (encryptedString != null && encryptedString.length() > 0) {
if (mCipher == null) {
throw new InvalidParameterException(
"Cipher is null. Please initialize proper cipher");
}
if (initCipher(mKeyAlias, Cipher.DECRYPT_MODE)) {
StringBuilder decryptedBuilder = new StringBuilder();
String[] chunks = encryptedString.split(CHUNK_SEPARATOR);
for (String chunk : chunks) {
byte[] bytes = Base64.decode(chunk, Base64.NO_WRAP);
decryptedBuilder.append(new String(mCipher.doFinal(bytes)));
}
return decryptedBuilder.toString();
}
}
return encryptedString;
} catch (IllegalBlockSizeException e) {
// We generate keys using UserAuthenticationValidityDurationSeconds parameter.
// We decrypt data by chunk. This exception could be if this validity duration ended
// during decryption. In this reason we check cause exception and provide valid
// exception to user space
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& e.getCause() instanceof UserNotAuthenticatedException) {
throw new OktaUserNotAuthenticateException(
getUserNotAuthenticatedMessage(mCipher), e);
}
throw e;
}
}