private static long readDataLength(FileStream stream, BlockStreamCrypter bsc) { byte[] buf = new byte[blockSize]; int trLen = stream.Read(buf, 0, blockSize); if (trLen != blockSize) { throw new Exception("Unable to read data length suffix."); } bsc.crypt(buf, 0); return(unpackDataLength(buf)); }
/** * Encrypts or decrypts a file. * * @param inputFileName * Name of the input file. * @param outputFileName * Name of the output file. * @param charKey * The encryption key. A string of ASCII characters within the range 0x21 .. 0x7E. * @param encrypt * true to encrypt, false to decrypt. * @param mode * Mode of operation. */ public static void cryptFile(String inputFileName, String outputFileName, String charKey, bool encrypt) { FileStream inStream = null; FileStream outStream = null; try { Idea idea = new Idea(charKey, encrypt); BlockStreamCrypter bsc = new BlockStreamCrypter(idea, encrypt); inStream = new FileStream(inputFileName, FileMode.Open, FileAccess.ReadWrite); long inFileSize = inStream.Length; long inDataLen; long outDataLen; if (encrypt) { inDataLen = inFileSize; outDataLen = (inDataLen + blockSize - 1) / blockSize * blockSize; } else { if (inFileSize == 0) { throw new IOException("Input file is empty."); } if (inFileSize % blockSize != 0) { throw new IOException("Input file size is not a multiple of " + blockSize + "."); } inDataLen = inFileSize - blockSize; outDataLen = inDataLen; } outStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write); processData(inStream, inDataLen, outStream, outDataLen, bsc); if (encrypt) { writeDataLength(outStream, inDataLen, bsc); } else { long outFileSize = readDataLength(inStream, bsc); if (outFileSize < 0 || outFileSize > inDataLen || outFileSize < inDataLen - blockSize + 1) { throw new IOException("Input file is not a valid cryptogram."); } if (outFileSize != outDataLen) { outStream.SetLength(outFileSize); } } outStream.Close(); } finally { if (inStream != null) { inStream.Close(); } if (outStream != null) { outStream.Close(); } } }
private static void writeDataLength(FileStream stream, long dataLength, BlockStreamCrypter bsc) { byte[] a = packDataLength(dataLength); bsc.crypt(a, 0); stream.Write(a, 0, blockSize); }
private static long readDataLength(FileStream stream, BlockStreamCrypter bsc) { byte[] buf = new byte[blockSize]; int trLen = stream.Read(buf, 0, blockSize); if (trLen != blockSize) { throw new Exception("Unable to read data length suffix."); } bsc.crypt(buf, 0); return unpackDataLength(buf); }
private static void processData(FileStream inStream, long inDataLen, FileStream outStream, long outDataLen, BlockStreamCrypter bsc) { int bufSize = 0x200000; byte[] buf = new byte[bufSize]; long filePos = 0; while (filePos < inDataLen) { int reqLen = (int)Math.Min(inDataLen - filePos, bufSize); int trLen = inStream.Read(buf, 0, reqLen); if (trLen != reqLen) { throw new Exception("Incomplete data chunk read from file."); } int chunkLen = (trLen + blockSize - 1) / blockSize * blockSize; for (int i = trLen; i <= chunkLen; i++) { buf[i] = 0; } for (int pos = 0; pos < chunkLen; pos += blockSize) { bsc.crypt(buf, pos); } reqLen = (int)Math.Min(outDataLen - filePos, chunkLen); outStream.Write(buf, 0, reqLen); filePos += chunkLen; } }