public void TestCompositeWatermark() { EncryptedWatermark.Algorithm = aes; CompositeWatermark comp = new CompositeWatermark(); TextWatermark mark1 = new TextWatermark("This is mark #1"); TextWatermark mark2 = new TextWatermark("This is mark #2"); EncryptedWatermark enc = new EncryptedWatermark(mark1, "supersecret"); comp.AddWatermark(mark1); comp.AddWatermark(mark2); Expect(comp.Watermarks.Count, Is.EqualTo(2)); comp.AddWatermark(enc); Expect(comp.Watermarks.Count, Is.EqualTo(3)); Watermarker.EmbedWatermark(file, comp, "password", "results/CompositeMark.png"); PNGFile file2 = new PNGFile("results/CompositeMark.png"); CompositeWatermark extract = (CompositeWatermark)Watermarker.ExtractWatermark(file2, "password"); System.Collections.Generic.List <Watermark> marks = extract.Watermarks; Expect(marks.Count, Is.EqualTo(3)); Assert.IsInstanceOf <TextWatermark>(marks[0]); Assert.IsInstanceOf <TextWatermark>(marks[1]); Assert.IsInstanceOf <EncryptedWatermark>(marks[2]); ((EncryptedWatermark)marks[2]).Decrypt("supersecret"); Expect(((TextWatermark)marks[0]).Text, Is.EqualTo("This is mark #1")); Expect(((TextWatermark)marks[1]).Text, Is.EqualTo("This is mark #2")); Expect(((EncryptedWatermark)marks[2]).Decrypt <TextWatermark>("supersecret").Text, Is.EqualTo("This is mark #1")); }
/// <summary> /// Extracts a stored watermark from a PNGFile. /// </summary> /// <param name="file">PNGFile that contains the watermark.</param> /// <param name="mark">An empty watermark that will be populated.</param> /// <param name="password">Password that was used to embed the watermark.</param> /// <returns></returns> public static Watermark ExtractWatermark(PNGFile file, string password) { Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, new byte[] { 112, 52, 63, 42, 180, 121, 53, 27 }, 1000); PNGScrambler scrambler = new PNGScrambler(file, bytes.GetBytes(16), bytes.GetBytes(8)); byte[] data = null; byte markType; if (ReedSolomonProtection == false) { byte[] type = ReadBytes(file, scrambler, 1); markType = type[0]; if (markType > 9) { return(null); } byte[] dword = ReadBytes(file, scrambler, 4, 1); int length = BitConverter.ToInt32(dword, 0); try { data = ReadBytes(file, scrambler, length, 5); } catch (Exception e) { return(null); } } else { byte[] rsType = ReadBytes(file, scrambler, 3, 0); byte[] type = correctErrors(rsType, 1); markType = type[0]; if ((markType & 0x80) != 0x80) { return(null); } markType ^= 0x80; byte[] rsLength = ReadBytes(file, scrambler, 12, 3); byte[] length = correctErrors(rsLength, 4); int markLength = BitConverter.ToInt32(length, 0); int position = 0; int numBlocks = (markLength / 256) + (markLength % 256 > 0 ? 1 : 0); MemoryStream msOut = new MemoryStream(); while (numBlocks > 0) { int bytesInBlock = (markLength - (position / 2) < 256 ? markLength - (position / 2) : 256); bytesInBlock *= 2; byte[] codeBytes = ReadBytes(file, scrambler, bytesInBlock, position + 15); byte[] fixedData = correctErrors(codeBytes, bytesInBlock / 2); msOut.Write(fixedData, 0, fixedData.Length); numBlocks--; position += bytesInBlock; } data = msOut.ToArray(); } Watermark mark = null; switch (markType) { case 1: mark = TextWatermark.LoadFromBytes(data); break; case 2: mark = FileWatermark.LoadFromBytes(data); break; case 3: mark = BinaryWatermark.LoadFromBytes(data); break; case 4: mark = CompositeWatermark.LoadFromBytes(data); break; case 9: mark = EncryptedWatermark.LoadFromBytes(data); break; } return(mark); }
static void Main(string[] args) { //bool goodArgs = parseArgs(new string[]{"-m=EMBED", "-i=TestImage.png", "-o=Output.png", "-p=password", "-t=Hello", "-t=World", "-f=TestFile.txt", "-f=TestFile.txt", "-b=03,2A,4C,BD", "-e", "-a=AES", "-k=supersecret"}); //bool goodArgs = parseArgs(new string[] { "-m=EXTRACT","-c","-i=Output.png", "-p=password", "-t=Hello", "-t=World", "-f=TestFile.txt", "-f=TestFile.txt", "-b=03,2A,4C,BD", "-e", "-a=AES", "-k=supersecret" }); bool goodArgs = parseArgs(args); if (goodArgs) { Watermarker.ReedSolomonProtection = ReedSolomon; if (Encrypt) { SymmetricAlgorithm algo = null; switch (Algorithm) { case "AES": algo = new RijndaelManaged(); break; } if (algo != null) { algo.Padding = PaddingMode.Zeros; } else { Console.WriteLine("Invalid Algorithm specified, valid options are [\"AES\"]"); return; } EncryptedWatermark.Algorithm = algo; } if (Mode.Equals("EMBED")) { Watermark finalMark; if (marks.Count > 1) { CompositeWatermark comp = new CompositeWatermark(); foreach (Watermark m in marks) { comp.AddWatermark(m); } finalMark = comp; } else { finalMark = marks[0]; } if (Encrypt) { finalMark = new EncryptedWatermark(finalMark, EncKey); } PNGFile fileIn = new PNGFile(InputFile); Watermarker.EmbedWatermark(fileIn, finalMark, Password, OutputFile); } else { PNGFile fileIn = new PNGFile(InputFile); Watermark mark = Watermarker.ExtractWatermark(fileIn, Password); List <Watermark> marks = new List <Watermark>(); // check to see if encrypted if (mark.GetType().Equals(typeof(EncryptedWatermark))) { Console.WriteLine("Detected an encrypted watermark."); if (Encrypt) { Console.WriteLine("Attempting to decrypt the watermark..."); mark = ((EncryptedWatermark)mark).Decrypt(EncKey); } else { Console.WriteLine("Encrypt flag was not set, unable to continue. Please try again with the -e flag and appropriate -a and -k values"); return; } } // check to see if it is a composite if (mark.GetType().Equals(typeof(CompositeWatermark))) { Console.WriteLine("Composite Watermark detected."); CompositeWatermark comp = (CompositeWatermark)mark; Console.WriteLine("Total of " + comp.Watermarks.Count + " Watermarks found."); foreach (Watermark m in comp.Watermarks) { marks.Add(m); } } else { Console.WriteLine("Found 1 watermark."); marks.Add(mark); } // check to see if only console output if (OnlyConsole) { foreach (Watermark m in marks) { Console.WriteLine(m); } } else { for (var x = 0; x < marks.Count; x++) { marks[x].Save(OutputFile + "\\" + "Watermark" + (x + 1)); } } } } Console.ReadKey(); }