private static bool Verify(byte[] signedaddon, out SignedAddonHeader header, out byte[] assembly) { using (var stream = new MemoryStream(signedaddon)) { using (var reader = new BinaryReader(stream)) { using (var rsaProvider = new RSACryptoServiceProvider(new CspParameters { ProviderType = 1 })) { using (var sha1 = new SHA1CryptoServiceProvider()) { rsaProvider.ImportCspBlob(Convert.FromBase64String(PublicKey)); var headerBuffer = reader.ReadBytes(Marshal.SizeOf(typeof(SignedAddonHeader))); var assemblyBuffer = reader.ReadBytes(signedaddon.Length - headerBuffer.Length); header = DeserializeStructure <SignedAddonHeader>(headerBuffer); bool result; switch (header.Data.SignatureVersion) { case "2": const int signatureSize = 320; var verifyBuffer = new byte[signedaddon.Length - signatureSize]; Array.Copy(signedaddon, signatureSize, verifyBuffer, 0, verifyBuffer.Length); result = rsaProvider.VerifyData(verifyBuffer, sha1, header.Signature); break; default: Log.Instance.DoLog("You are using an older version of the addon, support for older addons will be removed soon."); result = rsaProvider.VerifyData(assemblyBuffer, sha1, header.Signature); break; } if (result) { var key = CustomRsa.DecodeBlock(header.CryptoData.Key, new BigInteger(Exponent), new BigInteger(Modulus)); assembly = RijndaelHelper.Decrypt(assemblyBuffer, key, header.CryptoData.Salt, header.CryptoData.Iterations); return(true); } } } } } assembly = null; return(false); }
private static int Main(string[] args) { const string signVersion = "2"; if (args.Length == 1) { Console.WriteLine("Select an assembly to sign..."); return(1); } // collect addon data var filePath = args[0]; var devName = args.Length > 1 ? args[1] : FileVersionInfo.GetVersionInfo(filePath).CompanyName; var isLibrary = GetArg("--library", args) || filePath.EndsWith(".dll"); var nobuddy = GetArg("--nobuddy", args); // init var assembly = File.ReadAllBytes(filePath); var random = new Random(Environment.TickCount + assembly.Length); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { using (var rsaProvider = new RSACryptoServiceProvider(new CspParameters { ProviderType = 1 })) { using (var sha1 = new SHA1CryptoServiceProvider()) { rsaProvider.ImportCspBlob(Convert.FromBase64String(PrivateKey)); // header var header = new SignedAddonHeader { CryptoData = new SignedAddonCryptoData(), Data = new SignedAddonData() { CData = new byte[100] } }; // set addon data header.Data.SignatureVersion = signVersion; header.Data.Author = devName; header.Data.IsLibrary = isLibrary; header.Data.Version = FileVersionInfo.GetVersionInfo(filePath).FileVersion; header.Data.CData[0] = (byte)(nobuddy ? 1 : 0); header.Signature = new byte[320]; // encrypt var blockSize = random.Next(30, 50); var key = new byte[random.Next(400, 700)]; var salt = new byte[40]; var iterations = random.Next(1, 7); random.NextBytes(key); random.NextBytes(salt); VerifyKey(key, blockSize); assembly = RijndaelHelper.Encrypt(assembly, key, salt, iterations); var keybuffer = new byte[16400]; key = CustomRsa.EncodeBlock(key, new BigInteger(RsaExponentPrivate), new BigInteger(RsaModulus), blockSize); Array.Copy(key, 0, keybuffer, 0, key.Length); // set crypto data header.CryptoData.Salt = salt; header.CryptoData.Iterations = iterations; header.CryptoData.Key = keybuffer; // sign const int signatureSize = 320; var headerSize0 = Marshal.SizeOf(typeof(SignedAddonHeader)) - signatureSize; var signBuffer = new byte[headerSize0 + assembly.Length]; var buffer = new List <byte>(); buffer.AddRange(SerializeStructure(header)); buffer.AddRange(assembly); Array.Copy(buffer.ToArray(), signatureSize, signBuffer, 0, signBuffer.Length); header.Signature = rsaProvider.SignData(signBuffer, sha1); // write to stream // todo optimize writer.Write(SerializeStructure(header)); writer.Write(assembly); } } } // save var path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".ebaddon"); File.WriteAllBytes(path, stream.ToArray()); } return(0); }