/** * Initialize the builder from scratch */ public void Initialize(EncryptionInfo info, CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode) { this.info = info; if (cipherAlgorithm == null) { cipherAlgorithm = CipherAlgorithm.aes128; } if (cipherAlgorithm != CipherAlgorithm.aes128 && cipherAlgorithm != CipherAlgorithm.aes192 && cipherAlgorithm != CipherAlgorithm.aes256) { throw new EncryptedDocumentException("Standard encryption only supports AES128/192/256."); } if (hashAlgorithm == null) { hashAlgorithm = HashAlgorithm.sha1; } if (hashAlgorithm != HashAlgorithm.sha1) { throw new EncryptedDocumentException("Standard encryption only supports SHA-1."); } if (chainingMode == null) { chainingMode = ChainingMode.ecb; } if (chainingMode != ChainingMode.ecb) { throw new EncryptedDocumentException("Standard encryption only supports ECB chaining."); } if (keyBits == -1) { keyBits = cipherAlgorithm.defaultKeySize; } if (blockSize == -1) { blockSize = cipherAlgorithm.blockSize; } bool found = false; foreach (int ks in cipherAlgorithm.allowedKeySize) { found |= (ks == keyBits); } if (!found) { throw new EncryptedDocumentException("KeySize " + keyBits + " not allowed for Cipher " + cipherAlgorithm.ToString()); } header = new StandardEncryptionHeader(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode); verifier = new StandardEncryptionVerifier(cipherAlgorithm, hashAlgorithm, keyBits, blockSize, chainingMode); decryptor = new StandardDecryptor(this); encryptor = new StandardEncryptor(this); }
FileStream rawStream;// maybe has memory leak problem. protected internal StandardCipherOutputStream(DirectoryNode dir, StandardEncryptor encryptor) { this.encryptor = encryptor; this.dir = dir; fileOut = TempFile.CreateTempFile("encrypted_package", "crypt"); rawStream = new FileStream(fileOut.FullName, FileMode.Open, FileAccess.ReadWrite); // fileOut.Create(); // although not documented, we need the same padding as with agile encryption // and instead of calculating the missing bytes for the block size ourselves // we leave it up to the CipherOutputStream, which generates/saves them on close() // ... we can't use "NoPAdding" here // // see also [MS-OFFCRYPT] - 2.3.4.15 // The data block MUST be padded to the next integral multiple of the // KeyData.blockSize value. Any pAdding bytes can be used. Note that the StreamSize // field of the EncryptedPackage field specifies the number of bytes of // unencrypted data as specified in section 2.3.4.4. CipherOutputStream cryptStream = new CipherOutputStream(rawStream, encryptor.GetCipher(encryptor.GetSecretKey(), "PKCS5Padding")); this.out1 = cryptStream; }