public void AddCertificate(X509Certificate x509) { AgileCertificateEntry ace = new AgileCertificateEntry(); ace.x509 = x509; certList.Add(ace); }
/** * instead of a password, it's also possible to decrypt via certificate. * Warning: this code is experimental and hasn't been validated * * @see <a href="http://social.msdn.microsoft.com/Forums/en-US/cc9092bb-0c82-4b5b-ae21-abf643bdb37c/agile-encryption-with-certificates">Agile encryption with certificates</a> * * @param keyPair * @param x509 * @return true, when the data can be successfully decrypted with the given private key * @throws GeneralSecurityException */ public bool VerifyPassword(KeyPair keyPair, X509Certificate x509) { AgileEncryptionVerifier ver = (AgileEncryptionVerifier)builder.GetVerifier(); AgileEncryptionHeader header = (AgileEncryptionHeader)builder.GetHeader(); HashAlgorithm hashAlgo = header.HashAlgorithm; CipherAlgorithm cipherAlgo = header.CipherAlgorithm; int blockSize = header.BlockSize; AgileCertificateEntry ace = null; foreach (AgileCertificateEntry aceEntry in ver.GetCertificates()) { if (x509.Equals(aceEntry.x509)) { ace = aceEntry; break; } } if (ace == null) { return(false); } Cipher cipher = Cipher.GetInstance("RSA"); cipher.Init(Cipher.DECRYPT_MODE, keyPair.getPrivate()); byte[] keyspec = cipher.DoFinal(ace.encryptedKey); SecretKeySpec secretKey = new SecretKeySpec(keyspec, ver.CipherAlgorithm.jceId); Mac x509Hmac = CryptoFunctions.GetMac(hashAlgo); x509Hmac.Init(secretKey); byte[] certVerifier = x509Hmac.DoFinal(ace.x509.GetEncoded()); byte[] vec = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityKeyBlock, blockSize); cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE); byte[] hmacKey = cipher.DoFinal(header.GetEncryptedHmacKey()); hmacKey = GetBlock0(hmacKey, hashAlgo.hashSize); vec = CryptoFunctions.GenerateIv(hashAlgo, header.KeySalt, kIntegrityValueBlock, blockSize); cipher = GetCipher(secretKey, cipherAlgo, ver.ChainingMode, vec, Cipher.DECRYPT_MODE); byte[] hmacValue = cipher.DoFinal(header.GetEncryptedHmacValue()); hmacValue = GetBlock0(hmacValue, hashAlgo.hashSize); if (Arrays.Equals(ace.certVerifier, certVerifier)) { SetSecretKey(secretKey); SetIntegrityHmacKey(hmacKey); SetIntegrityHmacValue(hmacValue); return(true); } else { return(false); } }
protected internal AgileEncryptionVerifier(EncryptionDocument ed) { IEnumerator <CT_KeyEncryptor> encList = ed.GetEncryption().keyEncryptors.keyEncryptor.GetEnumerator(); CT_PasswordKeyEncryptor keyData; try { //keyData = encList.Next().EncryptedPasswordKey; encList.MoveNext(); keyData = encList.Current.Item as CT_PasswordKeyEncryptor; if (keyData == null) { throw new NullReferenceException("encryptedKey not Set"); } } catch (Exception e) { throw new EncryptedDocumentException("Unable to parse keyData", e); } int keyBits = (int)keyData.keyBits; CipherAlgorithm ca = CipherAlgorithm.FromXmlId(keyData.cipherAlgorithm.ToString(), keyBits); CipherAlgorithm = (ca); int hashSize = (int)keyData.hashSize; HashAlgorithm ha = HashAlgorithm.FromEcmaId(keyData.hashAlgorithm.ToString()); HashAlgorithm = (ha); if (HashAlgorithm.hashSize != hashSize) { throw new EncryptedDocumentException("Unsupported hash algorithm: " + keyData.hashAlgorithm + " @ " + hashSize + " bytes"); } SpinCount = (int)(keyData.spinCount); EncryptedVerifier = (keyData.encryptedVerifierHashInput); Salt = (keyData.saltValue); EncryptedKey = (keyData.encryptedKeyValue); EncryptedVerifierHash = (keyData.encryptedVerifierHashValue); int saltSize = (int)keyData.saltSize; if (saltSize != Salt.Length) { throw new EncryptedDocumentException("Invalid salt size"); } switch (keyData.cipherChaining) { case ST_CipherChaining.ChainingModeCBC: ChainingMode = (ChainingMode.cbc); break; case ST_CipherChaining.ChainingModeCFB: ChainingMode = (ChainingMode.cfb); break; default: throw new EncryptedDocumentException("Unsupported chaining mode - " + keyData.cipherChaining.ToString()); } //if (!encList.HasNext()) return; try { //CertificateFactory cf = CertificateFactory.GetInstance("X.509"); while (encList.MoveNext()) { CT_CertificateKeyEncryptor certKey = encList.Current.Item as CT_CertificateKeyEncryptor; AgileCertificateEntry ace = new AgileCertificateEntry(); ace.certVerifier = certKey.certVerifier; ace.encryptedKey = certKey.encryptedKeyValue; ace.x509 = new X509Certificate(X509CertificateStructure.GetInstance(certKey.X509Certificate)); certList.Add(ace); } } catch (Exception e) { throw new EncryptedDocumentException("can't parse X509 certificate", e); } }