/// <summary> /// Validate a file with a MinisignSignature and a MinisignPublicKey object. /// </summary> /// <param name="filePath">The full path to the file.</param> /// <param name="signature">A valid MinisignSignature object.</param> /// <param name="publicKey">A valid MinisignPublicKey object.</param> /// <returns><c>true</c> if valid; otherwise, <c>false</c>.</returns> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="OverflowException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> public static bool ValidateSignature(string filePath, MinisignSignature signature, MinisignPublicKey publicKey) { if (filePath != null && !File.Exists(filePath)) { throw new FileNotFoundException("could not find filePath"); } if (signature == null) { throw new ArgumentException("missing signature input", nameof(signature)); } if (publicKey == null) { throw new ArgumentException("missing publicKey input", nameof(publicKey)); } if (!ArrayHelpers.ConstantTimeEquals(signature.KeyId, publicKey.KeyId)) { return(false); } // load the file into memory var file = LoadMessageFile(filePath); // verify the signature if (PublicKeyAuth.VerifyDetached(signature.Signature, file, publicKey.PublicKey)) { // verify the trusted comment return(PublicKeyAuth.VerifyDetached(signature.GlobalSignature, ArrayHelpers.ConcatArrays(signature.Signature, signature.TrustedComment), publicKey.PublicKey)); } return(false); }
/// <summary> /// Validates server acceptance message /// </summary> /// <remark> /// Here the client verifies that the received message length is 80 /// bytes, then opens the encrypted box and verifies that the sent /// message is server's signature to the derived shared secrets. With /// this the handshake concludes. /// </remark> /// <exception cref="ArgumentException"> /// Thrown if the server's Accept <paramref name="msg"/> is not the /// correct size or the signature is not valid. /// </exception> /// <param name="msg"> /// The received message, encrypted server's signature. /// </param> public void VerifyAccept(byte[] msg) { if (msg.Length != 80) { throw new ArgumentException("Incorrect message size"); } var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); // Concatenate the network key and derived secrets to obtain // the message key var key = CryptoHash.Sha256( Utils.Concat(_network_key, _shared_ab, _shared_aB, _shared_Ab) ); var opened_msg = SecretBox.Open(msg, nonce, key); // Compute the message that it is supposed to be signed with the // server's long term key var hashed = CryptoHash.Sha256(_shared_ab); var msg_to_verify = Utils.Concat( _network_key, detached_signature_A, _longterm_client_keypair.PublicKey, hashed ); if (!PublicKeyAuth.VerifyDetached(opened_msg, msg_to_verify, _longterm_server_pk)) { throw new ArgumentException("Invalid signature"); } }
/// <summary> /// Validate a file with a MinisignSignature and a MinisignPublicKey object. /// </summary> /// <param name="message">The message to validate.</param> /// <param name="signature">A valid MinisignSignature object.</param> /// <param name="publicKey">A valid MinisignPublicKey object.</param> /// <returns><c>true</c> if valid; otherwise, <c>false</c>.</returns> /// <exception cref="OverflowException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> public static bool ValidateSignature(byte[] message, MinisignSignature signature, MinisignPublicKey publicKey) { if (message == null) { throw new ArgumentException("missing signature input", nameof(message)); } if (signature == null) { throw new ArgumentException("missing signature input", nameof(signature)); } if (publicKey == null) { throw new ArgumentException("missing publicKey input", nameof(publicKey)); } if (!ArrayHelpers.ConstantTimeEquals(signature.KeyId, publicKey.KeyId)) { return(false); } // verify the signature if (PublicKeyAuth.VerifyDetached(signature.Signature, message, publicKey.PublicKey)) { // verify the trusted comment return(PublicKeyAuth.VerifyDetached(signature.GlobalSignature, ArrayHelpers.ConcatArrays(signature.Signature, signature.TrustedComment), publicKey.PublicKey)); } return(false); }
public bool isValidSignature(Interaction interaction) { var signature = Context.Request.Headers["X-Signature-Ed25519"]; signature ??= Context.Request.Headers["X-Signature-Ed25519".ToLower()]; var timestamp = Context.Request.Headers["X-Signature-Timestamp"]; timestamp ??= Context.Request.Headers["X-Signature-Timestamp".ToLower()]; Program.LogMsg($"Verifying {timestamp} with {signature}"); var message = timestamp + Context.Body; var publicKey = Program.Configuration["tokens:publickey"]; #if !DEBUG if (!PublicKeyAuth.VerifyDetached( Sodium.Utilities.HexToBinary(signature), Encoding.UTF8.GetBytes(message), Sodium.Utilities.HexToBinary(publicKey))) { Program.LogMsg($"Failed verification."); return(false); } #endif Program.LogMsg($"Suceeded verification"); return(true); }
public void VerifyAuthDetachedBadSignature() { PublicKeyAuth.VerifyDetached( Utilities.HexToBinary("5436accbe258a6b252c1140f38d7b8dc6196619945818b72512b6a8019d86dfeeb56f40c4d4b983d97dfeed37948527256c3567d6b253757fcfb32bef56f0b"), Encoding.UTF8.GetBytes("Adam Caudill"), Utilities.HexToBinary("4ffda13c11d61d2b9568e54bec06ea59368e84874883087645e64e5e9653422e")); }
public void VerifyAuthDetachedBadSignature() { var signature = Utilities.HexToBinary("5436accbe258a6b252c1140f38d7b8dc6196619945818b72512b6a8019d86dfeeb56f40c4d4b983d97dfeed37948527256c3567d6b253757fcfb32bef56f0b"); var message = Encoding.UTF8.GetBytes("Adam Caudill"); var key = Utilities.HexToBinary("4ffda13c11d61d2b9568e54bec06ea59368e84874883087645e64e5e9653422e"); Assert.Throws <SignatureOutOfRangeException>( () => PublicKeyAuth.VerifyDetached(signature, message, key)); }
public void GenerateKeyVerifySignedDataTest() { var actual = PublicKeyAuth.GenerateKeyPair(); byte[] randomArray = SodiumCore.GetRandomBytes(255); var sign = PublicKeyAuth.SignDetached(randomArray, actual.PrivateKey); Assert.IsTrue(PublicKeyAuth.VerifyDetached(sign, randomArray, actual.PublicKey)); }
/// <summary> /// Create callback function for public key verification /// </summary> /// <remarks> /// PublicKeyVerifier sometimes required /// for peers that are receiving a static public key at some /// point during the handshake /// </remarks> /// <param name="rootPublicKey"></param> /// <returns>Callback delegate</returns> public static Config.PublicKeyVerifierDeligate CreatePublicKeyVerifier(byte[] rootPublicKey) { return((publicKey, proof) => { if (publicKey.Length != Asymmetric.DhLen) { return false; } return PublicKeyAuth.VerifyDetached(proof, publicKey, rootPublicKey); }); }
/// <summary> /// Checks for <paramref name="msg"/> length and validity, extracting /// the client's long term public key upon success. /// </summary> /// <param name="msg">Client authenticate message</param> /// <exception cref="ArgumentException"> /// Thrown if the client Auth <paramref name="msg"/> fails to pass the /// checks. /// </exception> public void AcceptAuth(byte[] msg) { if (msg.Length != 112) { throw new ArgumentException("Incorrect secretbox length"); } // A nonce consisting of 24 zeros var nonce = new byte[NONCE_SIZE]; nonce.Initialize(); // Calculate the decryption key from the dervided keys var key = CryptoHash.Sha256( Utils.Concat(_network_key, _shared_ab, _shared_aB) ); var opened_msg = SecretBox.Open(msg, nonce, key); if (opened_msg.Length != 96) { throw new ArgumentException("Invalid size of opened message"); } // Extract the signature of the long term client's public key // signed with the derived secret var detached_signature = new byte[SIG_SIZE]; Buffer.BlockCopy(opened_msg, 0, detached_signature, 0, SIG_SIZE); // Extract the long term client's public key var lt_cli_pk = new byte[PUB_KEY_SIZE]; Buffer.BlockCopy(opened_msg, SIG_SIZE, lt_cli_pk, 0, PUB_KEY_SIZE); var shared_hashed = CryptoHash.Sha256(_shared_ab); // Concat network_key, server longterm pk and sha256 hashed shared_ab secret var to_verify = Utils.Concat( _network_key, _longterm_server_keypair.PublicKey, shared_hashed ); if (!PublicKeyAuth.VerifyDetached(detached_signature, to_verify, lt_cli_pk)) { throw new ArgumentException("Signature does not match"); } detached_signature_A = detached_signature; _longterm_client_pk = lt_cli_pk; this.DeriveAb(); }
public void VerifyAuthDetachedBadKey() { //Don`t copy bobSk for other tests (bad key)! //30 byte var bobSk = new byte[] { 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88 }; PublicKeyAuth.VerifyDetached( Utilities.HexToBinary("8d5436accbe258a6b252c1140f38d7b8dc6196619945818b72512b6a8019d86dfeeb56f40c4d4b983d97dfeed37948527256c3567d6b253757fcfb32bef56f0b"), Encoding.UTF8.GetBytes("Adam Caudill"), bobSk); }
/// <summary> /// Returns true if the signature associated with a given message is valid /// </summary> /// <param name="response">Decrypted string representation of the response</param> /// <param name="signature">64 byte signature</param> /// <param name="publicKey">32 byte public key</param> /// <returns>`true` if the signature is valid, and false otherwise</returns> public bool IsSignatureValid(String response, byte[] signature, byte[] publicKey) { if (signature.Length != 64) { throw new ArgumentException(String.Format("Signature should be %d bytes.", 64)); } if (publicKey.Length != 32) { throw new ArgumentException(String.Format("Public key should be %d bytes.", 64)); } try { return(PublicKeyAuth.VerifyDetached( signature, System.Text.Encoding.UTF8.GetBytes(response), publicKey )); } catch (Exception e) { throw new SignatureVerificationException("Unable to calculate signature.", e); } }
public static bool VerifySignature(string signatureFilePath, string filePath, byte[] publicKey) { using var signatureFile = new FileStream(signatureFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.RandomAccess); // Verify the global signature byte[] magicBytes = GetMagicBytes(signatureFile); byte[] formatVersion = GetFormatVersion(signatureFile); FileHeaders.ValidateFormatVersion(signatureFilePath, formatVersion, Constants.SignatureVersion); byte[] preHashedHeader = GetPreHashedHeader(signatureFile); byte[] fileSignature = GetFileSignature(signatureFile); _commentBytes = GetCommentBytes(signatureFile); byte[] signatureFileBytes = Utilities.ConcatArrays(magicBytes, formatVersion, preHashedHeader, fileSignature, _commentBytes); bool validGlobalSignature = VerifyGlobalSignature(signatureFile, signatureFileBytes, publicKey); if (!validGlobalSignature) { return(false); } // Verify the file signature bool preHashed = BitConverter.ToBoolean(preHashedHeader); byte[] fileBytes = GetFileBytes(filePath, preHashed); return(PublicKeyAuth.VerifyDetached(fileSignature, fileBytes, publicKey)); }
public static bool VerifySignature(string signatureFilePath, string filePath, byte[] publicKey, out string comment) { using var signatureFile = new FileStream(signatureFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, Constants.FileStreamBufferSize, FileOptions.SequentialScan); byte[] magicBytes = GetMagicBytes(signatureFile); byte[] formatVersion = GetFormatVersion(signatureFile); FileHeaders.ValidateFormatVersion(formatVersion, Constants.SignatureVersion); byte[] preHashed = GetPreHashedHeader(signatureFile); byte[] fileSignature = GetFileSignature(signatureFile); byte[] commentBytes = GetCommentBytes(signatureFile); byte[] signatureFileBytes = Arrays.Concat(magicBytes, formatVersion, preHashed, fileSignature, commentBytes); bool validGlobalSignature = VerifyGlobalSignature(signatureFile, signatureFileBytes, publicKey); if (!validGlobalSignature) { comment = string.Empty; return(false); } bool preHash = BitConverter.ToBoolean(preHashed); byte[] fileBytes = GetFileBytes(filePath, preHash); comment = Encoding.UTF8.GetString(commentBytes); return(PublicKeyAuth.VerifyDetached(fileSignature, fileBytes, publicKey)); }
public void DetachedSignTest() { var kp = PublicKeyAuth.GenerateKeyPair(); string message = "Hello, World!"; byte[] byteMessage = System.Text.Encoding.UTF8.GetBytes(message); var sig1 = PublicKeyAuth.SignDetached(message, kp.Secret); var sig2 = PublicKeyAuth.SignDetached(byteMessage, kp.Secret); Assert.AreEqual(Convert.ToBase64String(sig1), Convert.ToBase64String(sig2)); Assert.AreEqual(64, sig1.Length); Assert.AreEqual(64, sig2.Length); Assert.IsTrue(PublicKeyAuth.VerifyDetached(sig1, byteMessage, kp.Public)); Assert.IsTrue(PublicKeyAuth.VerifyDetached(sig1, message, kp.Public)); Assert.IsTrue(PublicKeyAuth.VerifyDetached(sig2, byteMessage, kp.Public)); Assert.IsTrue(PublicKeyAuth.VerifyDetached(sig2, message, kp.Public)); var kp2 = PublicKeyAuth.GenerateKeyPair(); Assert.IsFalse(PublicKeyAuth.VerifyDetached(sig2, message, kp2.Public)); Assert.IsFalse(PublicKeyAuth.VerifyDetached(sig2, "Invalid message test", kp.Public)); }
public static bool Verify(byte[] signature, byte[] payload, byte[] publicKey) => PublicKeyAuth.VerifyDetached(signature, payload, publicKey);
public static bool ValidateSQRLPost(byte[] sig, string client, string server, byte[] key) { return(PublicKeyAuth.VerifyDetached(sig, (client + server).UTF8Bytes(), key)); }
static bool LibsodiumVerifyDetachedFromBase64(byte[] publicKey, string dataToSign, string signatureBase64) { byte[] data = System.Text.Encoding.UTF8.GetBytes(dataToSign); byte[] signature = Base64Decoding(signatureBase64); return(PublicKeyAuth.VerifyDetached(signature, data, publicKey)); }
public override void OnActionExecuting(ActionExecutingContext context) { if (_settings.Value.PublicKey == null) { return; } // Do something before the action executes. var request = context.HttpContext.Request; try { // Get the verification headers from the request ... var signature = request.Headers["X-Signature-Ed25519"].ToString(); var timestamp = request.Headers["X-Signature-Timestamp"].ToString(); // ... convert the signature and public key to byte[] to use in verification ... var byteSig = HexConverter.HexStringToByteArray(signature); // NOTE: This reads your Public Key that you need to store somewhere. var byteKey = HexConverter.HexStringToByteArray(_settings.Value.PublicKey); // ... read the body from the request ... if (byteSig.Length < 1 || byteKey.Length < 1) { _logger.LogWarning("Failed to validate POST request for Discord API."); context.Result = new UnauthorizedResult(); return; } var raw = request.BodyToString(); /* * using var reader = new StreamReader(request.Body); * if (reader.BaseStream.CanSeek) * reader.BaseStream.Seek(0, SeekOrigin.Begin); * string raw = reader.ReadToEndAsync().Result; * * reader.Dispose(); */ // ... add the timestamp and convert it to a byte[] ... string body = timestamp + raw; var byteBody = Encoding.Default.GetBytes(body); // ... run through a verification with all the byte[]s ... bool validated = PublicKeyAuth.VerifyDetached(byteSig, byteBody, byteKey); // ... if it is not validated ... if (!validated) { // ... log a warning and return a 401 Unauthorized. _logger.LogWarning("Failed to validate POST request for Discord API."); context.Result = new UnauthorizedResult(); // Unauthorized("Invalid Request Signature"); return; } else { // ... otherwise continue onwards. _logger.LogInformation("Received POST from Discord"); } } catch (Exception ex) { // ... if an error occurred, log the error and return at 401 Unauthorized. _logger.LogInformation(ex, "Decryption failed."); _logger.LogWarning("Failed to validate POST request for Discord API."); context.Result = new UnauthorizedResult();// Unauthorized("Invalid Request Signature"); return; } finally { //context.HttpContext.Request = request; } //request.Body.Position = 0; }
private static bool VerifyGlobalSignature(FileStream signatureFile, byte[] signatureFileBytes, byte[] publicKey) { byte[] globalSignature = GetGlobalSignature(signatureFile); return(PublicKeyAuth.VerifyDetached(globalSignature, signatureFileBytes, publicKey)); }
public static bool Verify(byte[] sign, byte[] msg, byte[] publicKey) { return(PublicKeyAuth.VerifyDetached(sign, msg, publicKey)); }
public override bool Verify(byte[] input, byte[] signature) => PublicKeyAuth.VerifyDetached(signature, input, ((SodiumSecurityKey)Key).PublicKey);
//[ApiExplorerSettings(IgnoreApi = true)] public async Task <IActionResult> DiscordEndpointHandler() { string raw; // Request validation try { // Get the verification headers from the request ... var signature = Request.Headers["X-Signature-Ed25519"].ToString(); var timestamp = Request.Headers["X-Signature-Timestamp"].ToString(); // ... convert the signature and public key to byte[] to use in verification ... var byteSig = Utils.HexStringToByteArray(signature); var byteKey = Utils.HexStringToByteArray(Startup.PublicKey); // ... read the body from the request ... using var reader = new StreamReader(Request.Body); if (reader.BaseStream.CanSeek) { reader.BaseStream.Seek(0, SeekOrigin.Begin); } raw = await reader.ReadToEndAsync(); // ... add the timestamp and convert it to a byte[] ... string body = timestamp + raw; var byteBody = Encoding.Default.GetBytes(body); // ... run through a verification with all the byte[]s ... bool validated = PublicKeyAuth.VerifyDetached(byteSig, byteBody, byteKey); // ... if it is not validated ... if (!validated) { // ... log a warning and return a 401 Unauthorized. _logger.LogWarning("Failed to validate POST request for Discord API."); return(Unauthorized("Invalid Request Signature")); } else { // ... otherwise continue onwards. _logger.LogInformation("Received POST from Discord"); } } catch (Exception ex) { // ... if an error occurred, log the error and return at 401 Unauthorized. _logger.LogInformation(ex, "Decryption failed."); _logger.LogWarning("Failed to validate POST request for Discord API."); return(Unauthorized("Invalid Request Signature")); } // Response parsing JObject json; try { // ... attempt to create a json object from the body ... json = JObject.Parse(raw); } catch { // ... if that fails, return a 400 Bad Request. return(BadRequest()); } // ... check to see if this is a ping to the webhook ... if (json.ContainsKey("type") && (int)json["type"] == (int)InteractionType.Ping) { return(Ok( JsonConvert.SerializeObject( new InteractionResponseBuilder() .WithType(InteractionResponseType.Pong) .Build() ) )); // ... and return the pong if it is. } else {// ... then pass the raw request body to the client ... var response = await Program.Slash.HandleWebhookPost(raw); if (response is not null) // ... if the clients response is not null ... { return(Ok(JsonConvert.SerializeObject(response))); // ... serialize it and send it. } else { return(BadRequest("Failed to parse request JSON.")); // ... or send a bad request message. } } }
/// <summary> /// Verifiies the message. /// </summary> /// <returns><c>true</c>, if sign was verifiyed, <c>false</c> otherwise.</returns> /// <param name="signature">Signature.</param> /// <param name="message">Message.</param> /// <param name="pk">Pk.</param> public static bool VerifiySign(byte[] signature, byte[] message, byte[] pk) => PublicKeyAuth.VerifyDetached(signature, message, pk);
public static bool VerifySignature(byte[] publicKey, byte[] signature, byte[] message) { return(PublicKeyAuth.VerifyDetached(signature, message, publicKey)); }