예제 #1
0
        public Bitmap HideData(string content, string secretKey)
        {
            if (!Readable())
            {
                throw new ApplicationException("Unable to read from this image.");
            }

            string inputKey       = null;
            var    contentToWrite = Encoding.UTF8.GetBytes(content);

            if (!string.IsNullOrEmpty(secretKey))
            {
                //Starts a new rjindael input key
                inputKey = Guid.NewGuid().ToString().Replace("-", "");

                var encryptedString = RjindaelHelper.EncryptRijndael(content, secretKey, inputKey);
                contentToWrite = Convert.FromBase64String(encryptedString);
            }

            var capacity = BitCapacity();
            int size     = contentToWrite.Length;

            byte[] sizeToBytes = BitConverter.GetBytes(size);
            var    contentSize = contentToWrite.Length + (sizeToBytes.Length * 8);

            if (!string.IsNullOrEmpty(secretKey))
            {
                contentSize = contentSize + 256;
            }

            if (contentSize > capacity)
            {
                throw new ApplicationException("Content is too big to hide on this image.");
            }

            var package = new List <byte>();

            package.AddRange(sizeToBytes);
            if (inputKey != null)
            {
                var inputKeyToASCIIBytes = Encoding.ASCII.GetBytes(inputKey);
                package.AddRange(inputKeyToASCIIBytes);
            }
            package.AddRange(contentToWrite);

            var bitsToWrite = new BitArray(package.ToArray());
            int bitIndex    = 0;

            _output.WriteLine($"Hiding {contentToWrite.Length * 8} bits...");

            var output = new Bitmap(Image.FromStream(_contentStream));
            int R = 0, G = 0, B = 0;

            _output.WriteLine($"Writing data...");

            //Loop again but write the data on the clean pixels
            for (int y = 0; y < output.Height; y++)
            {
                if (bitIndex >= bitsToWrite.Count)
                {
                    break;
                }
                for (int x = 0; x < output.Width; x++)
                {
                    if (bitIndex >= bitsToWrite.Count)
                    {
                        break;
                    }

                    Color pixel = output.GetPixel(x, y);

                    //Set the next 3 bits to write
                    var next3bits = new BitArray(new bool[] { false, false, false });
                    for (var index = 0; index < next3bits.Count; index++)
                    {
                        if (bitIndex >= bitsToWrite.Count)
                        {
                            continue;
                        }

                        next3bits[index] = bitsToWrite.Get(bitIndex);
                        bitIndex++;
                    }

                    //Remove the least significant bit value
                    R = pixel.R - pixel.R % 2;
                    G = pixel.G - pixel.G % 2;
                    B = pixel.B - pixel.B % 2;

                    //Apply the actual data
                    R = R + Convert.ToByte(next3bits[0]);
                    G = G + Convert.ToByte(next3bits[1]);
                    B = B + Convert.ToByte(next3bits[2]);

                    output.SetPixel(x, y, Color.FromArgb(R, G, B));
                }
            }

            return(output);
        }
예제 #2
0
        public static string ReadData(Bitmap bitmap, string secretKey)
        {
            var bitList = new List <bool>();
            var ended   = false;

            for (int y = 0; y < bitmap.Height; y++)
            {
                if (ended)
                {
                    break;
                }

                for (int x = 0; x < bitmap.Width; x++)
                {
                    if (ended)
                    {
                        break;
                    }

                    var pixel = bitmap.GetPixel(x, y);

                    var bit1 = Convert.ToBoolean(pixel.R % 2);
                    var bit2 = Convert.ToBoolean(pixel.G % 2);
                    var bit3 = Convert.ToBoolean(pixel.B % 2);

                    bitList.Add(bit1);
                    bitList.Add(bit2);
                    bitList.Add(bit3);
                }
            }

            var startIndex      = 32;
            var sizeBitArray    = new BitArray(bitList.GetRange(0, 32).ToArray());
            var outputSizeBytes = new byte[4];

            sizeBitArray.CopyTo(outputSizeBytes, 0);
            var outputSize = BitConverter.ToInt32(outputSizeBytes);

            Console.WriteLine($"Output size: {outputSize * 8} bits");

            string inputKey = null;

            if (!string.IsNullOrEmpty(secretKey))
            {
                startIndex = startIndex + 256;
                var inputKeyBitArray        = new BitArray(bitList.GetRange(32, 256).ToArray());
                var outputSizeInputKeyBytes = new byte[32];
                inputKeyBitArray.CopyTo(outputSizeInputKeyBytes, 0);
                inputKey = Encoding.ASCII.GetString(outputSizeInputKeyBytes).Trim();
            }

            bitList = bitList.GetRange(startIndex, (outputSize * 8));

            var outputArray = new BitArray(bitList.ToArray());

            if (outputArray.Count % 8 != 0)
            {
                throw new ApplicationException($"Invalid number of bits: {outputArray.Count}.");
            }

            var bytes = new byte[outputArray.Count / 8];

            outputArray.CopyTo(bytes, 0);

            string outputString = null;

            if (inputKey != null)
            {
                outputString = Convert.ToBase64String(bytes);
                outputString = RjindaelHelper.DecryptRijndael(outputString, secretKey, inputKey);
            }
            else
            {
                outputString = Encoding.UTF8.GetString(bytes);
            }

            return(outputString);
        }