Пример #1
0
        /// <summary>
        /// Encrypts a packet targeted to a single person
        /// </summary>
        /// <param name="packet">The packet to encrypt</param>
        /// <param name="targetPublicKey">Target's identity public key</param>
        /// <returns>Encrypted packet</returns>
        public static DEncodeValue EncryptTargetedPacket(DEncodeValue packet, byte[] targetPublicKey)
        {
            var targetCryptCsp = new RSACryptoServiceProvider();
            targetCryptCsp.ImportCspBlob(targetPublicKey);

            var packetStream = new MemoryStream();
            var writer = new DEncodeWriter(packetStream);
            writer.Write(packet);

            var packetBytes = packetStream.ToArray();
            // create a unique packet key
            var csp = CreatePacketCryptingAlgoInstance();
            var key = new byte[32];
            var iv = new byte[32];
            RngCsp.GetBytes(key);
            RngCsp.GetBytes(iv);

            csp.Key = key;
            csp.IV = iv;

            // encrypt the packet
            var cryptedPacketBytes = csp.CreateEncryptor().TransformFinalBlock(packetBytes, 0, packetBytes.Length);

            // now encrypt the packet key with the target's public key
            var encryptedKey = targetCryptCsp.Encrypt(key, true);

            var packetDict = new Dictionary<string, DEncodeValue>();
            packetDict.Add("ty", new DEncodeString("targeted")); // type (encrypted, targeted packet)
            packetDict.Add("ke", new DEncodeArray(encryptedKey)); // packet encryption key (encrypted with target's public key)
            packetDict.Add("iv", new DEncodeArray(iv)); // IV for the packet encryption
            packetDict.Add("pa", new DEncodeArray(cryptedPacketBytes)); // wrapped payload packet

            return new DEncodeDictionary(packetDict);
        }
Пример #2
0
        /// <summary>
        /// Encrypts a packet without any specific target (= targeting the whole chat session) using a master key
        /// </summary>
        /// <param name="packet">The packet to encrypt</param>
        /// <param name="masterKey">The master key to use for encryption</param>
        /// <returns>Encrypted packet</returns>
        public static DEncodeValue EncryptNonTargetedPacket(DEncodeValue packet, byte[] masterKey)
        {
            var packetStream = new MemoryStream();
            var writer = new DEncodeWriter(packetStream);
            writer.Write(packet);

            var packetBytes = packetStream.ToArray();
            // create a unique packet key
            var csp = CreatePacketCryptingAlgoInstance();

            var iv = new byte[32];
            RngCsp.GetBytes(iv);

            csp.Key = masterKey;
            csp.IV = iv;

            // encrypt the packet
            var cryptedPacketBytes = csp.CreateEncryptor().TransformFinalBlock(packetBytes, 0, packetBytes.Length);

            var packetDict = new Dictionary<string, DEncodeValue>();
            packetDict.Add("ty", new DEncodeString("nontargeted")); // type (encrypted, targeted packet)
            packetDict.Add("iv", new DEncodeArray(iv)); // IV for the packet encryption
            packetDict.Add("pa", new DEncodeArray(cryptedPacketBytes)); // wrapped payload packet

            return new DEncodeDictionary(packetDict);
        }
Пример #3
0
        /// <summary>
        /// Sends a Crype packet to the chatroom
        /// </summary>
        /// <param name="packet">Crype packet body</param>
        public void SendPacket(DEncodeValue packet)
        {
            var packetWriterStream = new MemoryStream();
            var packetWriter = new DEncodeWriter(packetWriterStream);
            packetWriter.Write(packet);

            var messageToSend = Convert.ToBase64String(packetWriterStream.ToArray());
            _chatImpl.SendMessage(messageToSend);
        }
Пример #4
0
        /// <summary>
        /// Parses a packet decrypting it if necessary. Returns the unwrapped plain packet and information about the options of the packet
        /// </summary>
        /// <param name="packet">The packet</param>
        /// <param name="targetedDecryptorCsp">RSA instance to decrypt targeted packets</param>
        /// <param name="untargetedMasterKey">Master key to decrypt untargeted packets on chat</param>
        /// <returns>The unwrapped packet and information about it</returns>
        public static PacketInfo UnwrapPacket(DEncodeValue packet, RSACryptoServiceProvider targetedDecryptorCsp,
                                              byte[] untargetedMasterKey)
        {
            var packetDict = (DEncodeDictionary) packet;
            var type = ((DEncodeString) packetDict.Items["ty"]).Value;
            if (type == "plain")
            {
                return new PacketInfo(packet, false, null, false, false);
            }

            if (type == "sigwrap")
            {
                var signedByKey = ((DEncodeArray) packetDict.Items["sb"]).Value;
                var signature = ((DEncodeArray) packetDict.Items["si"]).Value;
                var wrappedPacket = packetDict.Items["pa"];

                var packetStream = new MemoryStream();
                var writer = new DEncodeWriter(packetStream);
                writer.Write(wrappedPacket);
                var wrappedPacketBytes = packetStream.ToArray();

                var validatorCsp = new RSACryptoServiceProvider();
                validatorCsp.ImportCspBlob(signedByKey);

                if (!validatorCsp.VerifyHash(ComputeSha1Hash(wrappedPacketBytes), Sha1Csp.ToString(), signature))
                {
                    throw new CryptographicException("Invalid signature");
                }

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsSigned = true;
                wrappedPacketInfo.SignedByKey = signedByKey;
                return wrappedPacketInfo;
            }

            if (type == "targeted")
            {
                var encryptedPacketKey = ((DEncodeArray) packetDict.Items["ke"]).Value;
                var iv = ((DEncodeArray) packetDict.Items["iv"]).Value;
                var encryptedPacketBytes = ((DEncodeArray) packetDict.Items["pa"]).Value;

                // decrypt the packet key
                var packetKey = targetedDecryptorCsp.Decrypt(encryptedPacketKey, true);

                // decrypt the packet
                var decryptorCsp = CreatePacketCryptingAlgoInstance();
                decryptorCsp.Key = packetKey;
                decryptorCsp.IV = iv;

                var decryptedPacketBytes = decryptorCsp.CreateDecryptor()
                                                       .TransformFinalBlock(encryptedPacketBytes, 0,
                                                                            encryptedPacketBytes.Length);
                // parse the wrapped packet
                var reader = new DEncodeReader(new MemoryStream(decryptedPacketBytes));
                var wrappedPacket = reader.Read();

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsTargeted = true;
                return wrappedPacketInfo;
            }

            if (type == "nontargeted")
            {

                var iv = ((DEncodeArray)packetDict.Items["iv"]).Value;
                var encryptedPacketBytes = ((DEncodeArray)packetDict.Items["pa"]).Value;

                // decrypt the packet
                var decryptorCsp = CreatePacketCryptingAlgoInstance();
                decryptorCsp.Key = untargetedMasterKey;
                decryptorCsp.IV = iv;

                var decryptedPacketBytes = decryptorCsp.CreateDecryptor()
                                                       .TransformFinalBlock(encryptedPacketBytes, 0,
                                                                            encryptedPacketBytes.Length);
                // parse the wrapped packet
                var reader = new DEncodeReader(new MemoryStream(decryptedPacketBytes));
                var wrappedPacket = reader.Read();

                var wrappedPacketInfo = UnwrapPacket(wrappedPacket, targetedDecryptorCsp, untargetedMasterKey);
                wrappedPacketInfo.IsUntargeted = true;
                return wrappedPacketInfo;
            }

            throw new Exception("Invalid packet type code");
        }
Пример #5
0
        /// <summary>
        /// Signs a packet with RSA
        /// </summary>
        /// <param name="packet">The packet to sign</param>
        /// <param name="signingCsp">RSA instance with private key used to sign the packet</param>
        /// <returns>Signed packet</returns>
        public static DEncodeValue SignPacket(DEncodeValue packet, RSACryptoServiceProvider signingCsp)
        {
            var packetStream = new MemoryStream();
            var writer = new DEncodeWriter(packetStream);
            writer.Write(packet);

            // sign the wrapped packet
            var packetBytes = packetStream.ToArray();
            var packetHash = ComputeSha1Hash(packetBytes);

            var signature = signingCsp.SignHash(packetHash, Sha1Oid);

            // create a wrapper packet with the original packet inside it
            var packetDict = new Dictionary<string, DEncodeValue>();
            packetDict.Add("ty", new DEncodeString("sigwrap")); // type (signature wrapper)
            packetDict.Add("sb", new DEncodeArray(signingCsp.ExportCspBlob(false))); // public key blob of the signer
            packetDict.Add("si", new DEncodeArray(signature)); // signature of payload
            packetDict.Add("pa", packet); // wrapped payload packet

            return new DEncodeDictionary(packetDict);
        }