C# AES and RSA File Encryption - How to use IV? -
i'm writing program @ moment works under following scenario:
- i've got confidential log files need backup server.
- i have program generates these log files every day.
- these log files if ever need opened.
- i have 1 rsa public/private key pair.
- the program has rsa public key.
- i generate random aes key each time program makes 1 of these confidential files.
- the program uses aes key encrypt log file.
- i use rsa public key encrypt aes key
- i backup both aes encrypted file , rsa encrypted aes key server.
as far understand, protocol fitting use case.
the issue i'm having coding in c#. ran needing initialization vector(iv) aes encryption, tried encrypt along aes key using public rsa key on both. 512(2 * 256) size larger rsa happy encrypt. figured out since created initialization vector randomly each time aes key, can add iv front of aes ciphertext. however, i'm not sure code inserted in functions
any in right direction "protocol" or other ways write iv ciphertext great. thank in advance.
static public tuple<byte[], byte[]> encryptaes(byte[] toencryptaes, rsaparameters rsapublickey) { byte[] encryptedaes = null; byte[] encryptedrsa = null; using (memorystream ms = new memorystream()) { using (rijndaelmanaged aes = new rijndaelmanaged()) { aes.keysize = 256; aes.blocksize = 128; aes.mode = ciphermode.cbc; aes.generateiv(); aes.generatekey(); encryptedrsa = rsaencrypt(aes.key, rsapublickey); using (var cs = new cryptostream(ms, aes.createencryptor(), cryptostreammode.write)) { ms.write(aes.iv, 0, aes.keysize); //doesnt work here //can't use cs write stream else encrypt along file cs.write(toencryptaes, 0, toencryptaes.length); cs.close(); } encryptedaes = ms.toarray(); } } return new tuple<byte[], byte[]>(encryptedaes, encryptedrsa); } static public byte[] decryptaes(byte[] todecryptaes, byte[] aeskeyandiv, rsaparameters rsaprivatekey) { byte[] aeskey = rsadecrypt(aeskeyandiv, rsaprivatekey); using (memorystream ms = new memorystream()) { using (rijndaelmanaged aes = new rijndaelmanaged()) { aes.keysize = 256; aes.blocksize = 128; aes.key = aeskey; ms.read(aes.iv, 0, aes.keysize); //not sure if can read ms here aes.mode = ciphermode.cbc; using (var cs = new cryptostream(ms, aes.createdecryptor(), cryptostreammode.write)) { //would need move 0 256? cs.write(todecryptaes, 0, todecryptaes.length); cs.close(); } return ms.toarray(); } } }
you quite close, write out iv before create cryptostream
static public tuple<byte[], byte[]> encryptaes(byte[] toencryptaes, rsaparameters rsapublickey) { byte[] encryptedaes = null; byte[] encryptedrsa = null; using (memorystream ms = new memorystream()) { using (rijndaelmanaged aes = new rijndaelmanaged()) { aes.keysize = 256; aes.blocksize = 128; aes.mode = ciphermode.cbc; aes.generateiv(); aes.generatekey(); encryptedrsa = rsaencrypt(aes.key, rsapublickey); ms.write(aes.iv, 0, aes.keysize); //move write here. using (var cs = new cryptostream(ms, aes.createencryptor(), cryptostreammode.write)) { cs.write(toencryptaes, 0, toencryptaes.length); cs.close(); } encryptedaes = ms.toarray(); } } return new tuple<byte[], byte[]>(encryptedaes, encryptedrsa); }
for decrypt, make sure loop on read till have read byte[] iv, stream.read
not guaranteed read bytes asked read. make static method readfully
ensure bytes read.
private static byte[] readfully(stream stream, int length) { int offset = 0; byte[] buffer = new byte[length]; while(offset < length) { offset += stream.read(buffer, offset, length - offset); } return buffer; }
then use method read in iv. want use cs.read
not cs.write
read out encrypted data , put stream in read mode, easier use .copyto
, copy data new memorystream.
static public byte[] decryptaes(byte[] todecryptaes, byte[] aeskeyandiv, rsaparameters rsaprivatekey) { byte[] aeskey = rsadecrypt(aeskeyandiv, rsaprivatekey); using (memorystream source = new memorystream(todecryptaes)) { using (rijndaelmanaged aes = new rijndaelmanaged()) { aes.keysize = 256; aes.blocksize = 128; aes.key = aeskey; var iv = readfully(source, aes.keysize); aes.iv = iv; aes.mode = ciphermode.cbc; using (var cs = new cryptostream(source, aes.createdecryptor(), cryptostreammode.read)) { using(var dest = new memorystream()) { cs.copyto(dest); return dest.toarray(); } } } } }
Comments
Post a Comment