public void TestEax() { byte[] K = Hex.Decode("233952DEE4D5ED5F9B9C6D6FF80FF478"); byte[] N = Hex.Decode("62EC67F9C3A4A407FCB2A8C49031A8B3"); byte[] P = Hex.Decode("68656c6c6f20776f726c642121"); byte[] C = Hex.Decode("2f9f76cb7659c70e4be11670a3e193ae1bc6b5762a"); KeyParameter key = ParameterUtilities.CreateKeyParameter("AES", K); IBufferedCipher inCipher = CipherUtilities.GetCipher("AES/EAX/NoPadding"); IBufferedCipher outCipher = CipherUtilities.GetCipher("AES/EAX/NoPadding"); inCipher.Init(true, new ParametersWithIV(key, N)); byte[] enc = inCipher.DoFinal(P); if (!AreEqual(enc, C)) { Fail("ciphertext doesn't match in EAX"); } outCipher.Init(false, new ParametersWithIV(key, N)); byte[] dec = outCipher.DoFinal(C); if (!AreEqual(dec, P)) { Fail("plaintext doesn't match in EAX"); } try { inCipher = CipherUtilities.GetCipher("AES/EAX/PKCS5Padding"); Fail("bad padding missed in EAX"); } catch (SecurityUtilityException) { // expected } }
/// <summary> /// Generate an enveloped object that contains an CMS Enveloped Data /// object using the passed in key generator. /// </summary> private Stream Open( Stream outStream, string encryptionOid, CipherKeyGenerator keyGen) { byte[] encKeyBytes = keyGen.GenerateKey(); KeyParameter encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes); Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes); ICipherParameters cipherParameters; AlgorithmIdentifier encAlgID = GetAlgorithmIdentifier( encryptionOid, encKey, asn1Params, out cipherParameters); Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); foreach (RecipientInf recipient in recipientInfs) { try { recipientInfos.Add(recipient.ToRecipientInfo(encKey, rand)); } catch (IOException e) { throw new CmsException("encoding error.", e); } catch (InvalidKeyException e) { throw new CmsException("key inappropriate for algorithm.", e); } catch (GeneralSecurityException e) { throw new CmsException("error making encrypted content.", e); } } return(Open(outStream, encAlgID, cipherParameters, recipientInfos)); }
private KeyParameter CalculateAgreedWrapKey( string wrapAlg, AsymmetricKeyParameter senderPublicKey, AsymmetricKeyParameter receiverPrivateKey) { DerObjectIdentifier agreeAlgID = keyEncAlg.Algorithm; ICipherParameters senderPublicParams = senderPublicKey; ICipherParameters receiverPrivateParams = receiverPrivateKey; if (agreeAlgID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) { byte[] ukmEncoding = info.UserKeyingMaterial.GetOctets(); MQVuserKeyingMaterial ukm = MQVuserKeyingMaterial.GetInstance( Asn1Object.FromByteArray(ukmEncoding)); AsymmetricKeyParameter ephemeralKey = GetPublicKeyFromOriginatorPublicKey( receiverPrivateKey, ukm.EphemeralPublicKey); senderPublicParams = new MqvPublicParameters( (ECPublicKeyParameters)senderPublicParams, (ECPublicKeyParameters)ephemeralKey); receiverPrivateParams = new MqvPrivateParameters( (ECPrivateKeyParameters)receiverPrivateParams, (ECPrivateKeyParameters)receiverPrivateParams); } IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf( agreeAlgID, wrapAlg); agreement.Init(receiverPrivateParams); BigInteger agreedValue = agreement.CalculateAgreement(senderPublicParams); int wrapKeySize = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8; byte[] wrapKeyBytes = X9IntegerConverter.IntegerToBytes(agreedValue, wrapKeySize); return(ParameterUtilities.CreateKeyParameter(wrapAlg, wrapKeyBytes)); }
private KeyParameter CalculateAgreedWrapKey(string wrapAlg, AsymmetricKeyParameter senderPublicKey, AsymmetricKeyParameter receiverPrivateKey) { DerObjectIdentifier objectID = this.keyEncAlg.ObjectID; ICipherParameters cipherParameters = senderPublicKey; ICipherParameters cipherParameters2 = receiverPrivateKey; if (objectID.Id.Equals(CmsEnvelopedGenerator.ECMqvSha1Kdf)) { byte[] octets = this.info.UserKeyingMaterial.GetOctets(); MQVuserKeyingMaterial instance = MQVuserKeyingMaterial.GetInstance(Asn1Object.FromByteArray(octets)); AsymmetricKeyParameter publicKeyFromOriginatorPublicKey = this.GetPublicKeyFromOriginatorPublicKey(receiverPrivateKey, instance.EphemeralPublicKey); cipherParameters = new MqvPublicParameters((ECPublicKeyParameters)cipherParameters, (ECPublicKeyParameters)publicKeyFromOriginatorPublicKey); cipherParameters2 = new MqvPrivateParameters((ECPrivateKeyParameters)cipherParameters2, (ECPrivateKeyParameters)cipherParameters2); } IBasicAgreement basicAgreementWithKdf = AgreementUtilities.GetBasicAgreementWithKdf(objectID, wrapAlg); basicAgreementWithKdf.Init(cipherParameters2); BigInteger s = basicAgreementWithKdf.CalculateAgreement(cipherParameters); int qLength = GeneratorUtilities.GetDefaultKeySize(wrapAlg) / 8; byte[] keyBytes = X9IntegerConverter.IntegerToBytes(s, qLength); return(ParameterUtilities.CreateKeyParameter(wrapAlg, keyBytes)); }
public static byte[] Decrypt(byte[] ciphertextAndNonce, byte[] key) { // Retrieve the nonce and ciphertext. byte[] nonce = new byte[ALGORITHM_NONCE_SIZE]; byte[] ciphertext = new byte[ciphertextAndNonce.Length - ALGORITHM_NONCE_SIZE]; Array.Copy(ciphertextAndNonce, 0, nonce, 0, nonce.Length); Array.Copy(ciphertextAndNonce, nonce.Length, ciphertext, 0, ciphertext.Length); // Create the cipher instance and initialize. GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine()); KeyParameter keyParam = ParameterUtilities.CreateKeyParameter(ALGORITHM_NAME, key); ParametersWithIV cipherParameters = new ParametersWithIV(keyParam, nonce); cipher.Init(false, cipherParameters); // Decrypt and return result. byte[] plaintext = new byte[cipher.GetOutputSize(ciphertext.Length)]; int length = cipher.ProcessBytes(ciphertext, 0, ciphertext.Length, plaintext, 0); cipher.DoFinal(plaintext, length); return(plaintext); }
public static byte[] DecryptDES(byte[] cipherData, byte[] derivedKey) { byte[] output = null; try { KeyParameter keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey); IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING"); cipher.Init(false, keyparam); try { output = cipher.DoFinal(cipherData); } catch (System.Exception ex) { throw new CryptoException(ex.Message); } } catch { } return(output); }
public void Decode(TextReader vaultFileReader, byte[] password, Stream output) { var vaultFile = AnsibleVaultFile.Load(vaultFileReader); var cipher = CipherUtilities.GetCipher("AES/CTR/PKCS7Padding"); var pbkdf2 = new Rfc2898DeriveBytes(password, vaultFile.Salt, 10000, HashAlgorithmName.SHA256); var derived = pbkdf2.GetBytes(32 + 32 + 16); var cipherKeyBytes = derived.AsSpan(0, 32).ToArray(); var hmacKey = derived.AsSpan(32, 32).ToArray(); var iv = derived.AsSpan(64, 16).ToArray(); var hmac256 = new HMACSHA256(hmacKey); var actualhmac = hmac256.ComputeHash(vaultFile.EncryptedBytes); if (!actualhmac.AsSpan().SequenceEqual(vaultFile.ExpectedHMac)) { throw new InvalidKeyException("HMAC check error: invalid password"); } var cparam = new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cipherKeyBytes), iv); cipher.Init(false, cparam); var decrypted = cipher.DoFinal(vaultFile.EncryptedBytes); output.Write(decrypted.AsSpan()); }
public void Encode(byte[] data, byte[] password, byte[] salt, TextWriter output, string label, int width) { var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256); var derived = pbkdf2.GetBytes(32 + 32 + 16); var vaultFile = new AnsibleVaultFile(); vaultFile.Version = "1.1"; vaultFile.Algorithm = "AES256"; vaultFile.Salt = salt; var cipher = CipherUtilities.GetCipher("AES/CTR/PKCS7Padding"); var cipherKeyBytes = derived.AsSpan(0, 32).ToArray(); var hmacKey = derived.AsSpan(32, 32).ToArray(); var iv = derived.AsSpan(64, 16).ToArray(); var cparam = new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", cipherKeyBytes), iv); cipher.Init(true, cparam); var encrypted = cipher.DoFinal(data); var hmac256 = new HMACSHA256(hmacKey); vaultFile.EncryptedBytes = encrypted; vaultFile.ExpectedHMac = hmac256.ComputeHash(encrypted); AnsibleVaultFile.Save(vaultFile, output, label, width); }
byte[] DecryptFinal(byte[] cipherData, byte[] derivedKey) { byte[] output = null; try { var keyparam = ParameterUtilities.CreateKeyParameter("AES", derivedKey); var cipher = CipherUtilities.GetCipher("AES/CBC/PKCS5Padding"); cipher.Init(false, keyparam); try { output = cipher.DoFinal(cipherData); } catch (System.Exception) { throw new CryptoException("Invalid Data"); } } catch (Exception) { } return(output); }
protected void oidTest( string[] oids, string[] names, int groupSize) { byte[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; for (int i = 0; i != oids.Length; i++) { IBufferedCipher c1 = CipherUtilities.GetCipher(oids[i]); IBufferedCipher c2 = CipherUtilities.GetCipher(names[i]); CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator(oids[i]); KeyParameter k = ParameterUtilities.CreateKeyParameter(oids[i], kg.GenerateKey()); ICipherParameters cp = k; if (names[i].IndexOf("/ECB/") < 0) { cp = new ParametersWithIV(cp, new byte[16]); } c1.Init(true, cp); c2.Init(false, cp); byte[] result = c2.DoFinal(c1.DoFinal(data)); if (!AreEqual(data, result)) { Fail("failed OID test"); } if (k.GetKey().Length != (16 + ((i / groupSize) * 8))) { Fail("failed key length test"); } } }
/** * decrypt the content and return an input stream. */ public override CmsTypedStream GetContentStream( ICipherParameters key) { try { AlgorithmIdentifier kekAlg = AlgorithmIdentifier.GetInstance(info.KeyEncryptionAlgorithm); Asn1Sequence kekAlgParams = (Asn1Sequence)kekAlg.Parameters; byte[] encryptedKey = info.EncryptedKey.GetOctets(); string kekAlgName = DerObjectIdentifier.GetInstance(kekAlgParams[0]).Id; string cName = CmsEnvelopedHelper.Instance.GetRfc3211WrapperName(kekAlgName); IWrapper keyWrapper = WrapperUtilities.GetWrapper(cName); byte[] iv = Asn1OctetString.GetInstance(kekAlgParams[1]).GetOctets(); ICipherParameters parameters = ((CmsPbeKey)key).GetEncoded(kekAlgName); parameters = new ParametersWithIV(parameters, iv); keyWrapper.Init(false, parameters); AlgorithmIdentifier aid = GetActiveAlgID(); string alg = aid.ObjectID.Id; KeyParameter sKey = ParameterUtilities.CreateKeyParameter( alg, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); return(GetContentFromSessionKey(sKey)); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } }
/** * generate an enveloped object that contains an CMS Enveloped Data * object using the given provider and the passed in key generator. * @throws java.io.IOException */ private Stream Open( Stream outStr, string macOid, CipherKeyGenerator keyGen) { // FIXME Will this work for macs? byte[] encKeyBytes = keyGen.GenerateKey(); KeyParameter encKey = ParameterUtilities.CreateKeyParameter(macOid, encKeyBytes); Asn1Encodable asn1Params = GenerateAsn1Parameters(macOid, encKeyBytes); ICipherParameters cipherParameters; AlgorithmIdentifier macAlgId = GetAlgorithmIdentifier( macOid, encKey, asn1Params, out cipherParameters); Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); foreach (RecipientInfoGenerator rig in recipientInfoGenerators) { try { recipientInfos.Add(rig.Generate(encKey, rand)); } catch (InvalidKeyException e) { throw new CmsException("key inappropriate for algorithm.", e); } catch (GeneralSecurityException e) { throw new CmsException("error making encrypted content.", e); } } // FIXME Only passing key at the moment // return Open(outStr, macAlgId, cipherParameters, recipientInfos); return Open(outStr, macAlgId, encKey, recipientInfos); }
/** * decrypt the content and return an input stream. */ public override CmsTypedStream GetContentStream( ICipherParameters key) { try { byte[] encryptedKey = info.EncryptedKey.GetOctets(); IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyEncAlg.ObjectID.Id); keyWrapper.Init(false, key); KeyParameter sKey = ParameterUtilities.CreateKeyParameter( GetContentAlgorithmName(), keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); return(GetContentFromSessionKey(sKey)); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } }
/// <summary> /// 解密 /// </summary> /// <param name="data">待解密数据</param> /// <param name="key">密钥</param> /// <param name="iv">偏移量,ECB模式不用填写!</param> /// <param name="algorithm">密文算法</param> /// <returns>未加密原文数据</returns> public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv, string algorithm) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } var cipher = CipherUtilities.GetCipher(algorithm); if (iv == null) { cipher.Init(false, ParameterUtilities.CreateKeyParameter("DES", key)); } else { cipher.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("DES", key), iv)); } return(cipher.DoFinal(data)); }
/** * decrypt the content and return it as a byte array. */ public override CmsTypedStream GetContentStream( ICipherParameters key) { byte[] encryptedKey = _info.EncryptedKey.GetOctets(); string keyExchangeAlgorithm = GetExchangeEncryptionAlgorithmName(_keyEncAlg.ObjectID); try { IWrapper keyWrapper = WrapperUtilities.GetWrapper(keyExchangeAlgorithm); keyWrapper.Init(false, key); KeyParameter sKey = ParameterUtilities.CreateKeyParameter( _encAlg.ObjectID, keyWrapper.Unwrap(encryptedKey, 0, encryptedKey.Length)); return(GetContentFromSessionKey(sKey)); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } // catch (IllegalBlockSizeException e) catch (DataLengthException e) { throw new CmsException("illegal blocksize in message.", e); } // catch (BadPaddingException e) catch (InvalidCipherTextException e) { throw new CmsException("bad padding in message.", e); } }
private EncryptionResponse SealAes(KeyDataResponse keyDataResponse, string secret) { var plainText = Encoding.UTF8.GetBytes(secret); var bytes = keyDataResponse.Plaintext.ToArray(); var dataKey = new byte[32]; var hmacKey = new byte[32]; Buffer.BlockCopy(bytes, 0, dataKey, 0, 32); Buffer.BlockCopy(bytes, 32, hmacKey, 0, 32); IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding"); cipher.Init(true, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", dataKey), _initializationVector)); var cipherText = cipher.DoFinal(plainText); var hmac = new HMACSHA256(hmacKey); var hmacResult = hmac.ComputeHash(cipherText); return(new EncryptionResponse { CipherText = cipherText, Hmac = hmacResult }); }
static byte[] Encrypt(byte[] data, byte[] derivedKey) { byte[] output = null; try { var keyparam = ParameterUtilities.CreateKeyParameter("DES", derivedKey); var cipher = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING"); cipher.Init(true, keyparam); try { output = cipher.DoFinal(data); return(output); } catch (System.Exception ex) { throw new CryptoException("Invalid Data"); } } catch (Exception ex) { } return(output); }
public static byte[] AES_GCMDecrypt(byte[] cipherWithNonce, byte[] keyBytes) { // Gets nonce and ciphertext byte[] nonce = new byte[NONCE_SIZE]; byte[] ciphertext = new byte[cipherWithNonce.Length - NONCE_SIZE]; Array.Copy(cipherWithNonce, 0, nonce, 0, nonce.Length); Array.Copy(cipherWithNonce, nonce.Length, ciphertext, 0, ciphertext.Length); // Specify AES-GCM block cipher var blockCipher = new GcmBlockCipher(new AesEngine()); var keyParam = ParameterUtilities.CreateKeyParameter(ENCRYPTION_METHOD, keyBytes); var cipherParams = new ParametersWithIV(keyParam, nonce); blockCipher.Init(false, cipherParams); // Decrypt ciphertext byte[] cleartext = new byte[blockCipher.GetOutputSize(ciphertext.Length)]; int length = blockCipher.ProcessBytes(ciphertext, 0, ciphertext.Length, cleartext, 0); blockCipher.DoFinal(cleartext, length); return(cleartext); }
private static void decrypt(String privateKeyPath, String encryptedCEK, String iv, String encryptedRecordingPath, String decryptedRecordingPath) { // 2) Retrieve customer private key corresponding to public_key_sid and use it to decrypt base 64 decoded // encrypted_cek via RSAES-OAEP-SHA256-MGF1 Object pemObject; using (var txtreader = File.OpenText(@privateKeyPath)) pemObject = new PemReader(txtreader).ReadObject(); var privateKey = (RsaPrivateCrtKeyParameters)((pemObject.GetType() == typeof(AsymmetricCipherKeyPair)) ? ((AsymmetricCipherKeyPair)pemObject).Private : pemObject); var rsaDecryptEngine = CipherUtilities.GetCipher("RSA/ECB/OAEPWITHSHA256ANDMGF1PADDING"); rsaDecryptEngine.Init(false, privateKey); var encryptedCekArr = Convert.FromBase64String(encryptedCEK); var decryptedCekArr = rsaDecryptEngine.DoFinal(encryptedCekArr); // 3) Initialize a AES256-GCM SecretKey object with decrypted CEK and base 64 decoded iv var aesDecryptEngine = CipherUtilities.GetCipher("AES/GCM/NOPADDING"); KeyParameter keyParameter = ParameterUtilities.CreateKeyParameter("AES", decryptedCekArr); ICipherParameters cipherParameters = new ParametersWithIV(keyParameter, Convert.FromBase64String(iv)); aesDecryptEngine.Init(false, cipherParameters); // 4) Decrypt encrypted recording using the SecretKey var decryptedFile = File.Create(@decryptedRecordingPath); CipherStream cipherStream = new CipherStream(File.OpenRead(@encryptedRecordingPath), aesDecryptEngine, null); cipherStream.CopyTo(decryptedFile); decryptedFile.Close(); }
private void doTestAlgorithm( string name, byte[] keyBytes, byte[] iv, byte[] plainText, byte[] cipherText) { KeyParameter key = ParameterUtilities.CreateKeyParameter(name, keyBytes); IBufferedCipher inCipher = CipherUtilities.GetCipher(name); IBufferedCipher outCipher = CipherUtilities.GetCipher(name); if (iv != null) { inCipher.Init(true, new ParametersWithIV(key, iv)); outCipher.Init(false, new ParametersWithIV(key, iv)); } else { inCipher.Init(true, key); outCipher.Init(false, key); } byte[] enc = inCipher.DoFinal(plainText); if (!AreEqual(enc, cipherText)) { Fail(name + ": cipher text doesn't match"); } byte[] dec = outCipher.DoFinal(enc); if (!AreEqual(dec, plainText)) { Fail(name + ": plain text doesn't match"); } }
public override void PerformTest() { for (int i = 0; i != cipherTests1.Length; i += 2) { doTest(cipherTests1[i], input1, Hex.Decode(cipherTests1[i + 1])); } for (int i = 0; i != cipherTests2.Length; i += 2) { doTest(cipherTests2[i], input2, Hex.Decode(cipherTests2[i + 1])); } // // check for less than a block // try { IBufferedCipher c = CipherUtilities.GetCipher("AES/CTS/NoPadding"); c.Init(true, ParameterUtilities.CreateKeyParameter("AES", new byte[16])); c.DoFinal(new byte[4]); Fail("CTS failed to throw exception"); } catch (Exception e) { // if (!(e is IllegalBlockSizeException)) if (!(e is DataLengthException)) { Fail("CTS exception test - " + e, e); } } doTestExceptions(); }
/** * decrypt the content and return an input stream. */ public override CmsTypedStream GetContentStream( // Key key) ICipherParameters key) { if (!(key is AsymmetricKeyParameter)) { throw new ArgumentException("KeyAgreement requires asymmetric key", "key"); } AsymmetricKeyParameter privKey = (AsymmetricKeyParameter)key; if (!privKey.IsPrivate) { throw new ArgumentException("Expected private key", "key"); } try { OriginatorPublicKey origK = _info.Originator.OriginatorKey; PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(privInfo.AlgorithmID, origK.PublicKey.GetBytes()); AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(pubInfo); string wrapAlg = DerObjectIdentifier.GetInstance( Asn1Sequence.GetInstance(_keyEncAlg.Parameters)[0]).Id; IBasicAgreement agreement = AgreementUtilities.GetBasicAgreementWithKdf( _keyEncAlg.ObjectID, wrapAlg); agreement.Init(privKey); BigInteger wKeyNum = agreement.CalculateAgreement(pubKey); // TODO Fix the way bytes are derived from the secret byte[] wKeyBytes = wKeyNum.ToByteArrayUnsigned(); KeyParameter wKey = ParameterUtilities.CreateKeyParameter(wrapAlg, wKeyBytes); IWrapper keyCipher = WrapperUtilities.GetWrapper(wrapAlg); keyCipher.Init(false, wKey); AlgorithmIdentifier aid = _encAlg; string alg = aid.ObjectID.Id; byte[] encryptedKey = _encryptedKey.GetOctets(); byte[] sKeyBytes = keyCipher.Unwrap(encryptedKey, 0, encryptedKey.Length); KeyParameter sKey = ParameterUtilities.CreateKeyParameter(alg, sKeyBytes); return(GetContentFromSessionKey(sKey)); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } catch (Exception e) { throw new CmsException("originator key invalid.", e); } }
/// <summary>Return the decrypted input stream, using the passed in passphrase.</summary> public Stream GetDataStream(char[] passPhrase) { try { var keyAlgorithm = _keyData.EncAlgorithm; var key = PgpUtilities.MakeKeyFromPassPhrase( keyAlgorithm, _keyData.S2K, passPhrase); var secKeyData = _keyData.GetSecKeyData(); if (secKeyData != null && secKeyData.Length > 0) { var keyCipher = CipherUtilities.GetCipher( PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding"); keyCipher.Init(false, new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()])); var keyBytes = keyCipher.DoFinal(secKeyData); keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0]; key = ParameterUtilities.CreateKeyParameter( PgpUtilities.GetSymmetricCipherName(keyAlgorithm), keyBytes, 1, keyBytes.Length - 1); } var c = CreateStreamCipher(keyAlgorithm); var iv = new byte[c.GetBlockSize()]; c.Init(false, new ParametersWithIV(key, iv)); EncStream = BcpgInputStream.Wrap(new CipherStream(EncData.GetInputStream(), c, null)); if (EncData is SymmetricEncIntegrityPacket) { TruncStream = new TruncatedStream(EncStream); var digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); var digest = DigestUtilities.GetDigest(digestName); EncStream = new DigestStream(TruncStream, digest, null); } if (Streams.ReadFully(EncStream, iv, 0, iv.Length) < iv.Length) { throw new EndOfStreamException("unexpected end of stream."); } var v1 = EncStream.ReadByte(); var v2 = EncStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is not deemed // a security risk for PBE (see PgpPublicKeyEncryptedData) var repeatCheckPassed = iv[iv.Length - 2] == (byte)v1 && iv[iv.Length - 1] == (byte)v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes var zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PgpDataValidationException("quick check failed."); } return(EncStream); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } }
// TODO Make private again and call from PerformTest public void doTestExceptions() { // TODO Put back in // SecretKeyFactory skF = null; // // try // { // skF = SecretKeyFactory.getInstance("DESede"); // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } // // KeySpec ks = null; // SecretKey secKey = null; // byte[] bb = new byte[24]; // // try // { // skF.getKeySpec(null, null); // // Fail("failed exception test - no exception thrown"); // } // catch (InvalidKeySpecException e) // { // // ignore okay // } // catch (Exception e) // { // Fail("failed exception test.", e); // } // try // { // ks = (KeySpec)new DESedeKeySpec(bb); // skF.getKeySpec(null, ks.getClass()); // // Fail("failed exception test - no exception thrown"); // } // catch (InvalidKeySpecException e) // { // // ignore okay; // } // catch (Exception e) // { // Fail("failed exception test.", e); // } // try // { // skF.getKeySpec(secKey, null); // } // catch (InvalidKeySpecException e) // { // // ignore okay // } // catch (Exception e) // { // Fail("failed exception test.", e); // } try { CipherKeyGenerator kg = GeneratorUtilities.GetKeyGenerator("DESede"); try { kg.Init(new KeyGenerationParameters(new SecureRandom(), int.MinValue)); Fail("failed exception test - no exception thrown"); } // catch (InvalidParameterException) catch (ArgumentException) { // ignore okay } catch (Exception e) { Fail("failed exception test.", e); } } catch (Exception e) { Fail("unexpected exception.", e); } // TODO Put back in // try // { // skF = SecretKeyFactory.getInstance("DESede"); // // try // { // skF.translateKey(null); // // Fail("failed exception test - no exception thrown"); // } // catch (InvalidKeyException) // { // // ignore okay // } // catch (Exception e) // { // Fail("failed exception test.", e); // } // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } // try // { // byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, // (byte)137, (byte)138, (byte)140, (byte)143 }; // //// SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); // KeyParameter cipherKey = new DesParameters(rawDESKey); // // IBufferedCipher cipher = CipherUtilities.GetCipher("DES/CBC/NoPadding"); // // try // { // // According specification engineInit(int opmode, Key key, // // SecureRandom random) throws InvalidKeyException if this // // cipher is being // // initialized for decryption and requires algorithm parameters // // that cannot be determined from the given key //// cipher.Init(false, cipherKey, (SecureRandom)null); // cipher.Init(false, new ParametersWithRandom(cipherKey, new SecureRandom())); // // Fail("failed exception test - no InvalidKeyException thrown"); // } // catch (InvalidKeyException) // { // // ignore // } // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } try { // byte[] rawDESKey = { -128, -125, -123, -122, -119, -118 }; byte[] rawDESKey = { 128, 131, 133, 134, 137, 138 }; // SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); // IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding"); try { KeyParameter cipherKey = new DesParameters(rawDESKey); // According specification engineInit(int opmode, Key key, // SecureRandom random) throws InvalidKeyException if the given // key is inappropriate for initializing this cipher // cipher.Init(true, cipherKey); // Fail("failed exception test - no InvalidKeyException thrown"); Fail("failed exception test - no ArgumentException thrown"); } // catch (InvalidKeyException) catch (ArgumentException) { // ignore } } catch (Exception e) { Fail("unexpected exception.", e); } // try // { //// byte[] rawDESKey = { -128, -125, -123, -122, -119, -118, -117, -115, -114 }; // byte[] rawDESKey = { 128, 131, 133, 134, 137, 138, 139, 141, 142 }; // //// SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); // KeyParameter cipherKey = new DesParameters(rawDESKey); // // IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/NoPadding"); // try // { // // According specification engineInit(int opmode, Key key, // // SecureRandom random) throws InvalidKeyException if the given // // key is inappropriate for initializing this cipher // cipher.Init(true, cipherKey); // // Fail("failed exception test - no InvalidKeyException thrown"); // } // catch (InvalidKeyException) // { // // ignore // } // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } try { byte[] rawDESKey = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; // SecretKeySpec cipherKey = new SecretKeySpec(rawDESKey, "DES"); KeyParameter cipherKey = new DesParameters(rawDESKey); IBufferedCipher ecipher = CipherUtilities.GetCipher("DES/ECB/PKCS5Padding"); ecipher.Init(true, cipherKey); byte[] cipherText = new byte[0]; try { // According specification Method engineUpdate(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result // ecipher.update(new byte[20], 0, 20, cipherText); ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0); // Fail("failed exception test - no ShortBufferException thrown"); Fail("failed exception test - no DataLengthException thrown"); } // catch (ShortBufferException) catch (DataLengthException) { // ignore } } catch (Exception e) { Fail("unexpected exception.", e); } // TODO Put back in // try // { // KeyGenerator keyGen = KeyGenerator.getInstance("DES"); // // keyGen.init((SecureRandom)null); // // // According specification engineGenerateKey() doesn't throw any exceptions. // // SecretKey key = keyGen.generateKey(); // if (key == null) // { // Fail("key is null!"); // } // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } // // try // { // AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES"); // // algParams.init(new IvParameterSpec(new byte[8])); // // // According specification engineGetEncoded() returns // // the parameters in their primary encoding format. The primary // // encoding // // format for parameters is ASN.1, if an ASN.1 specification for // // this type // // of parameters exists. // byte[] iv = algParams.getEncoded(); // // if (iv.Length!= 10) // { // Fail("parameters encoding wrong length - " + iv.Length); // } // } // catch (Exception e) // { // Fail("unexpected exception.", e); // } try { try { // AlgorithmParameters algParams = AlgorithmParameters.getInstance("DES"); byte[] encoding = new byte[10]; encoding[0] = 3; encoding[1] = 8; // algParams.init(encoding, "ASN.1"); ParameterUtilities.GetCipherParameters( "AES", ParameterUtilities.CreateKeyParameter("AES", new byte[16]), Asn1Object.FromByteArray(encoding)); // Fail("failed exception test - no IOException thrown"); Fail("failed exception test - no Exception thrown"); } // catch (IOException) catch (ArgumentException) { // okay } // try // { // IBufferedCipher c = CipherUtilities.GetCipher("DES"); // // Key k = new PublicKey() // { // // public string getAlgorithm() // { // return "STUB"; // } // // public string getFormat() // { // return null; // } // // public byte[] getEncoded() // { // return null; // } // // }; // // c.Init(true, k); // // Fail("failed exception test - no InvalidKeyException thrown for public key"); // } // catch (InvalidKeyException e) // { // // okay // } // // try // { // IBufferedCipher c = CipherUtilities.GetCipher("DES"); // // Key k = new PrivateKey() // { // // public string getAlgorithm() // { // return "STUB"; // } // // public string getFormat() // { // return null; // } // // public byte[] getEncoded() // { // return null; // } // // }; // // c.Init(false, k); // // Fail("failed exception test - no InvalidKeyException thrown for private key"); // } // catch (InvalidKeyException e) // { // // okay // } } catch (Exception e) { Fail("unexpected exception.", e); } }
private void doTest( string algorithm, byte[] input, byte[] output) { KeyParameter key = null; CipherKeyGenerator keyGen; SecureRandom rand; IBufferedCipher inCipher = null, outCipher = null; byte[] iv = null; CipherStream cIn, cOut; MemoryStream bIn, bOut; rand = new FixedSecureRandom(); string[] parts = algorithm.ToUpper(CultureInfo.InvariantCulture).Split('/'); string baseAlgorithm = parts[0]; string mode = parts.Length > 1 ? parts[1] : null; #if !INCLUDE_IDEA if (baseAlgorithm.Equals("IDEA")) { return; } #endif try { keyGen = GeneratorUtilities.GetKeyGenerator(baseAlgorithm); // TODO Add Algorithm property to CipherKeyGenerator? // if (!keyGen.getAlgorithm().Equals(baseAlgorithm)) // { // Fail("wrong key generator returned!"); // } // TODO Add new Init method to CipherKeyGenerator? // keyGen.Init(rand); keyGen.Init(new KeyGenerationParameters(rand, keyGen.DefaultStrength)); byte[] keyBytes = keyGen.GenerateKey(); if (algorithm.StartsWith("RC5")) { key = new RC5Parameters(keyBytes, rc5Rounds); } else { key = ParameterUtilities.CreateKeyParameter(baseAlgorithm, keyBytes); } inCipher = CipherUtilities.GetCipher(algorithm); outCipher = CipherUtilities.GetCipher(algorithm); if (!inCipher.AlgorithmName.ToUpper(CultureInfo.InvariantCulture).StartsWith(baseAlgorithm)) { Fail("wrong cipher returned!"); } ICipherParameters parameters = key; int ivLength = GetIVLength(algorithm); if (ivLength > 0) { if (baseAlgorithm == "RC2") { iv = rc2IV; } else if (baseAlgorithm == "RC5") { iv = rc5IV; } else if (baseAlgorithm == "RC5-64") { iv = rc564IV; } else { // NB: rand always generates same values each test run iv = rand.GenerateSeed(ivLength); } parameters = new ParametersWithIV(key, iv); } // NB: 'rand' still needed e.g. for some paddings parameters = new ParametersWithRandom(parameters, rand); outCipher.Init(true, parameters); } catch (Exception e) { Fail("" + algorithm + " failed initialisation - " + e.ToString(), e); } // // grab the iv if there is one // try { // The Java version set this implicitly, but we set it explicity //byte[] iv = outCipher.getIV(); if (iv != null) { // TODO Examine short IV handling for these FIPS-compliant modes in Java build if (mode.StartsWith("CFB") || mode.StartsWith("GOFB") || mode.StartsWith("OFB") || mode.StartsWith("OPENPGPCFB")) { // These modes automatically pad out the IV if it is short } else { try { byte[] nIv = new byte[iv.Length - 1]; inCipher.Init(false, new ParametersWithIV(key, nIv)); Fail("failed to pick up short IV"); } //catch (InvalidAlgorithmParameterException e) catch (ArgumentException) { // ignore - this is what we want... } } //IvParameterSpec spec = new IvParameterSpec(iv); inCipher.Init(false, new ParametersWithIV(key, iv)); } else { inCipher.Init(false, key); } } catch (Exception e) { Fail("" + algorithm + " failed initialisation - " + e.ToString()); } // // encryption pass // bOut = new MemoryStream(); cOut = new CipherStream(bOut, null, outCipher); try { for (int i = 0; i != input.Length / 2; i++) { cOut.WriteByte(input[i]); } cOut.Write(input, input.Length / 2, input.Length - input.Length / 2); cOut.Close(); } catch (IOException e) { Fail("" + algorithm + " failed encryption - " + e.ToString()); } byte[] bytes = bOut.ToArray(); if (!AreEqual(bytes, output)) { Fail("" + algorithm + " failed encryption - expected " + Hex.ToHexString(output) + " got " + Hex.ToHexString(bytes)); } // // decryption pass // bIn = new MemoryStream(bytes, false); cIn = new CipherStream(bIn, inCipher, null); try { BinaryReader dIn = new BinaryReader(cIn); bytes = new byte[input.Length]; for (int i = 0; i != input.Length / 2; i++) { bytes[i] = dIn.ReadByte(); } int remaining = bytes.Length - input.Length / 2; byte[] extra = dIn.ReadBytes(remaining); if (extra.Length < remaining) { throw new EndOfStreamException(); } extra.CopyTo(bytes, input.Length / 2); } catch (Exception e) { Fail("" + algorithm + " failed decryption - " + e.ToString()); } if (!AreEqual(bytes, input)) { Fail("" + algorithm + " failed decryption - expected " + Hex.ToHexString(input) + " got " + Hex.ToHexString(bytes)); } }
/// <summary> /// Generate an enveloped object that contains a CMS Enveloped Data /// object using the passed in key generator. /// </summary> private CmsEnvelopedData Generate( CmsProcessable content, string encryptionOid, CipherKeyGenerator keyGen) { AlgorithmIdentifier encAlgId = null; KeyParameter encKey; Asn1OctetString encContent; try { byte[] encKeyBytes = keyGen.GenerateKey(); encKey = ParameterUtilities.CreateKeyParameter(encryptionOid, encKeyBytes); Asn1Encodable asn1Params = GenerateAsn1Parameters(encryptionOid, encKeyBytes); ICipherParameters cipherParameters; encAlgId = GetAlgorithmIdentifier( encryptionOid, encKey, asn1Params, out cipherParameters); IBufferedCipher cipher = CipherUtilities.GetCipher(encryptionOid); cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); MemoryStream bOut = new MemoryStream(); CipherStream cOut = new CipherStream(bOut, null, cipher); content.Write(cOut); Platform.Dispose(cOut); encContent = new BerOctetString(bOut.ToArray()); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } catch (IOException e) { throw new CmsException("exception decoding algorithm parameters.", e); } Asn1EncodableVector recipientInfos = new Asn1EncodableVector(); foreach (RecipientInfoGenerator rig in recipientInfoGenerators) { try { recipientInfos.Add(rig.Generate(encKey, rand)); } catch (InvalidKeyException e) { throw new CmsException("key inappropriate for algorithm.", e); } catch (GeneralSecurityException e) { throw new CmsException("error making encrypted content.", e); } } EncryptedContentInfo eci = new EncryptedContentInfo( CmsObjectIdentifiers.Data, encAlgId, encContent); Asn1Set unprotectedAttrSet = null; if (unprotectedAttributeGenerator != null) { Asn1.Cms.AttributeTable attrTable = unprotectedAttributeGenerator.GetAttributes(Platform.CreateHashtable()); unprotectedAttrSet = new BerSet(attrTable.ToAsn1EncodableVector()); } ContentInfo contentInfo = new ContentInfo( CmsObjectIdentifiers.EnvelopedData, new EnvelopedData(null, new DerSet(recipientInfos), eci, unprotectedAttrSet)); return(new CmsEnvelopedData(contentInfo)); }
private void doRunTest( string name, int ivLength) { string lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789"; string baseName = name; if (name.IndexOf('/') >= 0) { baseName = name.Substring(0, name.IndexOf('/')); } CipherKeyGenerator kGen = GeneratorUtilities.GetKeyGenerator(baseName); IBufferedCipher inCipher = CipherUtilities.GetCipher(name); IBufferedCipher outCipher = CipherUtilities.GetCipher(name); KeyParameter key = ParameterUtilities.CreateKeyParameter(baseName, kGen.GenerateKey()); MemoryStream bIn = new MemoryStream(Encoding.ASCII.GetBytes(lCode), false); MemoryStream bOut = new MemoryStream(); // In the Java build, this IV would be implicitly created and then retrieved with getIV() ICipherParameters cipherParams = key; if (ivLength > 0) { cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]); } inCipher.Init(true, cipherParams); // TODO Should we provide GetIV() method on IBufferedCipher? //if (inCipher.getIV() != null) //{ // outCipher.Init(false, new ParametersWithIV(key, inCipher.getIV())); //} //else //{ // outCipher.Init(false, key); //} outCipher.Init(false, cipherParams); CipherStream cIn = new CipherStream(bIn, inCipher, null); CipherStream cOut = new CipherStream(bOut, null, outCipher); int c; while ((c = cIn.ReadByte()) >= 0) { cOut.WriteByte((byte)c); } cIn.Close(); cOut.Flush(); cOut.Close(); byte[] bs = bOut.ToArray(); string res = Encoding.ASCII.GetString(bs, 0, bs.Length); if (!res.Equals(lCode)) { Fail("Failed - decrypted data doesn't match."); } }
private void doTestException( string name, int ivLength) { try { byte[] key128 = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; byte[] key256 = { (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143, (byte)128, (byte)131, (byte)133, (byte)134, (byte)137, (byte)138, (byte)140, (byte)143 }; byte[] keyBytes; if (name.Equals("HC256")) { keyBytes = key256; } else { keyBytes = key128; } KeyParameter cipherKey = ParameterUtilities.CreateKeyParameter(name, keyBytes); ICipherParameters cipherParams = cipherKey; if (ivLength > 0) { cipherParams = new ParametersWithIV(cipherParams, new byte[ivLength]); } IBufferedCipher ecipher = CipherUtilities.GetCipher(name); ecipher.Init(true, cipherParams); byte[] cipherText = new byte[0]; try { // According specification Method engineUpdate(byte[] input, // int inputOffset, int inputLen, byte[] output, int // outputOffset) // throws ShortBufferException - if the given output buffer is // too // small to hold the result ecipher.ProcessBytes(new byte[20], 0, 20, cipherText, 0); // Fail("failed exception test - no ShortBufferException thrown"); Fail("failed exception test - no DataLengthException thrown"); } // catch (ShortBufferException e) catch (DataLengthException) { // ignore } // NB: The lightweight engine doesn't take public/private keys // try // { // IBufferedCipher c = CipherUtilities.GetCipher(name); // // // Key k = new PublicKey() // // { // // // // public string getAlgorithm() // // { // // return "STUB"; // // } // // // // public string getFormat() // // { // // return null; // // } // // // // public byte[] getEncoded() // // { // // return null; // // } // // // // }; // AsymmetricKeyParameter k = new AsymmetricKeyParameter(false); // c.Init(true, k); // // Fail("failed exception test - no InvalidKeyException thrown for public key"); // } // catch (InvalidKeyException) // { // // okay // } // // try // { // IBufferedCipher c = CipherUtilities.GetCipher(name); // // // Key k = new PrivateKey() // // { // // // // public string getAlgorithm() // // { // // return "STUB"; // // } // // // // public string getFormat() // // { // // return null; // // } // // // // public byte[] getEncoded() // // { // // return null; // // } // // // // }; // // AsymmetricKeyParameter k = new AsymmetricKeyParameter(true); // c.Init(false, k); // // Fail("failed exception test - no InvalidKeyException thrown for private key"); // } // catch (InvalidKeyException) // { // // okay // } } catch (Exception e) { Fail("unexpected exception.", e); } }
public static void extractAsTar(String backupFilename, String filename, String password) { try { Stream inStream = AndroidBackup.getInputStream(backupFilename); CipherStream cipherStream = null; String magic = AndroidBackup.readHeaderLine(inStream); // 1 if (DEBUG) { Console.WriteLine(("Magic: " + magic)); } String versionStr = AndroidBackup.readHeaderLine(inStream); // 2 if (DEBUG) { Console.WriteLine(("Version: " + versionStr)); } int version = int.Parse(versionStr); if (((version < BACKUP_FILE_V1) || (version > BACKUP_FILE_V4))) { throw new ArgumentException("Don\'t know how to process version " + versionStr); } String compressed = AndroidBackup.readHeaderLine(inStream); // 3 bool isCompressed = (int.Parse(compressed) == 1); if (DEBUG) { Console.WriteLine(("Compressed: " + compressed)); } String encryptionAlg = AndroidBackup.readHeaderLine(inStream); // 4 if (DEBUG) { Console.WriteLine(("Algorithm: " + encryptionAlg)); } bool isEncrypted = false; if (encryptionAlg.Equals(ENCRYPTION_ALGORITHM_NAME)) { isEncrypted = true; //if ((Cipher.getMaxAllowedKeyLength("AES") < MASTER_KEY_SIZE)) //{ // Console.WriteLine("WARNING: Maximum allowed key-Length seems smaller than needed. " + // "Please check that unlimited strength cryptography is available, see README.md for details"); //} if (((password == null) || "".Equals(password))) { Console.WriteLine("This backup is encrypted, please provide the password: "******"Invalid salt Length: " + userSalt.Length)); } String ckSaltHex = AndroidBackup.readHeaderLine(inStream); // 6 byte[] ckSalt = AndroidBackup.hexToByteArray(ckSaltHex); int rounds = int.Parse(AndroidBackup.readHeaderLine(inStream)); // 7 String userIvHex = AndroidBackup.readHeaderLine(inStream); // 8 String masterKeyBlobHex = AndroidBackup.readHeaderLine(inStream); // 9 // decrypt the master key blob IBufferedCipher c = CipherUtilities.GetCipher(ENCRYPTION_MECHANISM); // XXX we don't support non-ASCII passwords byte[] userKey = AndroidBackup.buildPasswordKey(password, userSalt, rounds, false); byte[] IV = AndroidBackup.hexToByteArray(userIvHex); byte[] ivSpec = IV; c.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES256", userKey), ivSpec)); //c.Init(false, new ParametersWithIV(new KeyParameter(userKey), ivSpec)); byte[] mkCipher = AndroidBackup.hexToByteArray(masterKeyBlobHex); byte[] mkBlob = c.DoFinal(mkCipher); // first, the master key IV int offset = 0; int len = mkBlob[offset++]; IV = Arrays.CopyOfRange(mkBlob, offset, (offset + len)); if (DEBUG) { Console.WriteLine(("IV: " + AndroidBackup.toHex(IV))); } offset = (offset + len); // then the master key itself len = mkBlob[offset++]; byte[] mk = Arrays.CopyOfRange(mkBlob, offset, (offset + len)); if (DEBUG) { Console.WriteLine(("MK: " + AndroidBackup.toHex(mk))); } offset = (offset + len); // and finally the master key checksum hash len = mkBlob[offset++]; byte[] mkChecksum = Arrays.CopyOfRange(mkBlob, offset, (offset + len)); if (DEBUG) { Console.WriteLine(("MK checksum: " + AndroidBackup.toHex(mkChecksum))); } // now validate the decrypted master key against the checksum // first try the algorithm matching the archive version bool useUtf = (version >= BACKUP_FILE_V2); byte[] calculatedCk = AndroidBackup.makeKeyChecksum(mk, ckSalt, rounds, useUtf); Console.Error.WriteLine("Calculated MK checksum (use UTF-8: {0}): {1}\n", useUtf, AndroidBackup.toHex(calculatedCk)); if (!Arrays.Equals(calculatedCk, mkChecksum)) { Console.WriteLine("Checksum does not match."); // try the reverse calculatedCk = AndroidBackup.makeKeyChecksum(mk, ckSalt, rounds, !useUtf); Console.Error.WriteLine("Calculated MK checksum (use UTF-8: {0}): {1}\n", useUtf, AndroidBackup.toHex(calculatedCk)); } // Even if checksum doesn't match, it works .. No idea why.// // if (Arrays.Equals(calculatedCk, mkChecksum)) { ivSpec = IV; c.Init(false, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES256", mk), ivSpec)); //c.init(Cipher.DECRYPT_MODE, new byte[]Spec(mk, "AES"), ivSpec); // Only if all of the above worked properly will 'result' be // assigned cipherStream = new CipherStream(inStream, c, null); } } if ((isEncrypted && (cipherStream == null))) { throw new Exception("Invalid password or master key checksum."); } Stream baseStream = isEncrypted ? cipherStream : inStream; Stream input = isCompressed ? new ZInputStream(baseStream) : baseStream; Stream output = null; try { output = getOutputStream(filename); byte[] buff = new byte[(10 * 1024)]; int read = -1; int totalRead = 0; while ((read = input.Read(buff, 0, buff.Length)) > 0) { output.Write(buff, 0, read); totalRead = (totalRead + read); if ((DEBUG && ((totalRead % (100 * 1024)) == 0))) { Console.Error.WriteLine("{0} bytes written\n", totalRead); } } Console.Error.WriteLine("{0} bytes written to {1}.\n", totalRead, backupFilename); } finally { if (input != null) { input.Close(); } if (output != null) { output.Flush(); output.Close(); } } } catch (Exception e) { throw; } }
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize) { keySize /= 8; byte[] keyBytes = GenerateDerivedKey(keySize); return(ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize)); }