//http://blog.differentpla.net/blog/2013/03/18/using-bouncy-castle-from-net public void CreateCertTest() { const string subject = "test"; // ReSharper disable once UnusedVariable //const string password = "******"; //// ReSharper disable once UnusedVariable //const int strength = 1024; var certService = new CertificateService { RandomPasswordSize = 4 }; using (var certificate = certService.CreateCert(subject)) { var publicKeyProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key; var privateKeyProvider = (RSACryptoServiceProvider)certificate.PrivateKey; var rsaService = RsaService.Create(certificate); var exportedCertBytes = certificate.Export(X509ContentType.Pfx); var exportedCertBytes2 = certificate.Export(X509ContentType.Cert); var exportedCertBytesReparsed = new X509Certificate2(exportedCertBytes); var exportedCertBytes2Reparsed = new X509Certificate2(exportedCertBytes2); Assert.IsNotNull(exportedCertBytesReparsed); Assert.IsNotNull(exportedCertBytes2Reparsed); Assert.AreEqual(publicKeyProvider.ToXmlString(false), privateKeyProvider.ToXmlString(false)); Assert.AreEqual(rsaService.PrivateKey, privateKeyProvider.ToXmlString(true)); Assert.AreEqual(rsaService.PublicKey, privateKeyProvider.ToXmlString(false)); } }
public void DigitalSignatureTest() { var aesService = new AesService(); (byte[] aesKey, byte[] aesIv) = aesService.CreateKey(); const string messageData = "this is a test message"; var messageBytes = Encoding.UTF8.GetBytes(messageData); var sender = RsaService.Create(); var receiver = RsaService.Create(); var hasher = new Sha256BitHasher(); var hashedMessageBytes = hasher.CreateHash(messageBytes); var digitalSignature = sender.EncryptPrivate(hashedMessageBytes); var cryptoBytes = aesService.Encrypt(messageBytes, aesKey, aesIv); var hashMessageBytesFromSignature = receiver.DecryptPublic(digitalSignature, sender.PublicKey); var plainMessageBytes = aesService.Decrypt(cryptoBytes, aesKey, aesIv); var hashedPlainMessageBytes = hasher.CreateHash(plainMessageBytes); Assert.IsTrue(hashMessageBytesFromSignature.SequenceEqual(hashedPlainMessageBytes)); }
public void KeyDeliveryTest() { //const string plainText = "this is the test plain data"; var aesService = new AesService(); (byte[] aesKey, byte[] aesIv) = aesService.CreateKey(); var combinedBytes = aesKey.Concat(aesIv).ToArray(); var client = RsaService.Create(); var server = RsaService.Create(); //send client aes encryption data from client to server var cryptoBytes = client.Encrypt(combinedBytes, server.PublicKey); var receivedClientAesData = server.Decrypt(cryptoBytes); var receivedClientAesKey = receivedClientAesData.Take(32).ToArray(); var receivedClientAesIv = receivedClientAesData.Reverse().Take(16).Reverse().ToArray(); Assert.IsTrue(aesKey.SequenceEqual(receivedClientAesKey)); Assert.IsTrue(aesIv.SequenceEqual(receivedClientAesIv)); //send client aes encrypted message using received key and iv const string responseToClientMessage = "I got your key thanks"; var responseToClientBytes = Encoding.UTF8.GetBytes(responseToClientMessage); var responseToClientBytesCryptoBytes = aesService.Encrypt(responseToClientBytes, receivedClientAesKey, receivedClientAesIv); //client decrypts server's response message var messageToClientBytes = aesService.Decrypt(responseToClientBytesCryptoBytes, aesKey, aesIv); var messageToClientText = Encoding.UTF8.GetString(messageToClientBytes); Assert.IsTrue(responseToClientBytes.SequenceEqual(messageToClientBytes)); Assert.AreEqual(responseToClientMessage, messageToClientText); }
public UserController(UserService userService, IMemoryCache memoryCache, ILogger <UserController> logger, RsaService rsaService, RsaServerKeys rsaServerKeys) { _userService = userService; _memoryCache = memoryCache; _logger = logger; _rsaService = rsaService; _rsaServerKeys = rsaServerKeys; }
public MainWindow() { InitializeComponent(); _httpClient = new HttpClient { BaseAddress = new Uri(CommonEnvironment.HostServer) }; _rsaService = new RsaService(); }
public RsaController(RsaServerKeys rsaServerKeys, IMemoryCache memoryCache, RsaService rsaService, ILogger <RsaController> logger) { _rsaServerKeys = rsaServerKeys; _memoryCache = memoryCache; _rsaService = rsaService; _logger = logger; }
/// <summary> /// Create a default RSA public key /// </summary> /// <param name="receiver">The target receiver</param> /// <param name="isSender">Is </param> /// <returns>CipherKey object</returns> /// <remarks>This method will be used when cannot get receiver's public key from KMS</remarks> public async Task <CipherKey> CreateDefaultAsymmetricKey(KeyTypeEnum keyType, bool isIncludePrivateKey = true) { switch (keyType) { case KeyTypeEnum.RSA: using (var rsa = new RsaService()) { return(await rsa.CreateKeyAsync()); } default: throw new NotImplementedException(); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(); services.AddScoped <UserService>(); services.AddMemoryCache(); services.AddSwaggerGen(opt => { opt.SwaggerDoc("v1", new Info { Title = "Документация API", Version = "v1" }); opt.DescribeAllEnumsAsStrings(); }); var rsaKeys = RsaService.GetKeyPair(); var serverKeys = new RsaServerKeys(rsaKeys.PublicKey, rsaKeys.PrivateKey); services.AddRsaService(); services.AddSingleton(serverKeys); }
/// <summary> /// 获取AES回执 /// </summary> /// <returns></returns> private async Task <ApplyAESEncryptKeyResponse> GetDefaultAesKey(bool getnew = false) { var result = await _cacheManager.GetCache(AppConsts.Cache_AesKeyModal).GetOrDefaultAsync("AesKeyResult"); if (result == null || getnew) { UserLoginSoapClient client = new UserLoginSoapClient(UserLoginSoapClient.EndpointConfiguration.UserLoginSoap); RSAParameters publicKey = RsaService.GetRsaPublicKey(); ApplyAESEncryptKeyResponse AesResult = await client.ApplyAESEncryptKeyAsync(new ApplyAESEncryptKeyRequest { DeviceCode = deviceCode, Modulus = Convert.ToBase64String(publicKey.Modulus), Exponent = Convert.ToBase64String(publicKey.Exponent) }); await _cacheManager.GetCache(AppConsts.Cache_AesKeyModal).SetAsync("AesKeyResult", AesResult); return(AesResult); } else { ApplyAESEncryptKeyResponse AesResult = (ApplyAESEncryptKeyResponse)result; return(AesResult); } }
public AsymmetricControllerFixture() { var svc = new RsaService(); controller = new AsymmetricController(svc); }
/// <summary> /// Send the request /// </summary> /// <param name="request">Request</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>HttpResponseMessage</returns> protected override async Task <HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { #region Get receiver-name and retry-times from Http Header // Retry Times request.Headers.TryGetValues(CustomHttpHeaderFactory.RetryTimes, out IEnumerable <string> retryTimesValues); int retryTimes = 0; int.TryParse(retryTimesValues.FirstOrDefault(), out retryTimes); // RequestCacheId request.Headers.TryGetValues(CustomHttpHeaderFactory.RequestCacheId, out IEnumerable <string> requestCacheIdValues); var requestCacheId = requestCacheIdValues.FirstOrDefault(); #endregion #region Encrypt the Http Request (Only in the first time) if (retryTimes.Equals(0)) { this.logger.LogDebug($"Start encrypting request..."); using (var rsa = new RsaService()) { #region Get public key var publicKey = await this.keyManager.GetPublicKeyAsync(KeyTypeEnum.RSA); #endregion #region Get original payload // Load payload string content = await request.Content.ReadAsStringAsync(); // Remove escapted character, eq. "\"xxxxx\"" => "xxxxx" var jsonPayload = JsonConvert.DeserializeObject <string>(content); #endregion #region Save the original payload before encrypted var cacheKey = requestCacheId; this.memoryCache.Set(cacheKey, jsonPayload, DateTimeOffset.Now.AddSeconds(CacheRequestTimeout)); this.logger.LogDebug($"Successfully caching original request to memory cache: {cacheKey}."); #endregion #region Encrypt // Encrypt string encryptedPayload = await rsa.EncryptAsync(publicKey, jsonPayload); // Replace the original content with the encrypted one var newContent = new System.Net.Http.StringContent($"\"{encryptedPayload}\"", Encoding.UTF8, "application/json"); ////newContent.Headers.ContentType.CharSet = string.Empty; request.Content = newContent; this.logger.LogDebug($"Successfully encrypting request."); #endregion } } #endregion // base.SendAsync calls the inner handler var response = await base.SendAsync(request, cancellationToken); return(response); }
public async Task MakeSessionAsync(string acessToken, string refreshToken = null) { var rsa = new RsaService(); var aes = new AesCrypt(); var rsaPair = rsa.GenerateKeys(); var strongKeyRequest = new { publicKey = rsaPair.publicKey }; var authRequest = new AuthRequest(acessToken); string strongKeyJsonRequest = JsonConvert.SerializeObject(strongKeyRequest); var strongKeyRequestMessage = authRequest.BuildRequestMessage(ConfigurationManager.AppSettings.Get("devUrl") + Urls.GetStrongKeyUrl, HttpMethod.Post, strongKeyJsonRequest); var strongKeyResponseMessage = await authRequest.httpClient.SendAsync(strongKeyRequestMessage); if (strongKeyResponseMessage.StatusCode == HttpStatusCode.NotFound) { var firstSessionRequestModel = new CreateMessangerSessionRequest() { PublicKey = rsaPair.publicKey }; string jsonRequest = JsonConvert.SerializeObject(firstSessionRequestModel); var firstSessionResponse = await authRequest.GetStringFromHttpResultAsync(ConfigurationManager.AppSettings.Get("devUrl") + Urls.CreateFirstSessionUrl, HttpMethod.Post, jsonRequest); var response = JsonConvert.DeserializeObject <CreateFirstMessangerSessionResponse>(firstSessionResponse); string decryptedAesKey = rsa.Decrypt(rsaPair.privateKey, response.CryptedAes); byte[] decryptedAesKeyBuffer = decryptedAesKey.FromUrlSafeBase64(); await userProvider.CreateStrongKeyAsync(UserId, decryptedAesKeyBuffer); string newToken = await tokenService.MakeAuthTokenAsync(UserId, true); authRequest = new AuthRequest(newToken); rsaPair = rsa.GenerateKeys(); string cryptedPublicKey = aes.Crypt(decryptedAesKeyBuffer.ToUrlSafeBase64(), rsaPair.publicKey); var sessionRequestModel = new CreateMessangerSessionRequest() { PublicKey = cryptedPublicKey }; jsonRequest = JsonConvert.SerializeObject(sessionRequestModel); var httpRequest = authRequest.BuildRequestMessage(ConfigurationManager.AppSettings.Get("devUrl") + Urls.CreateSessionUrl, HttpMethod.Post, jsonRequest); var sessionResponse = await authRequest.httpClient.SendAsync(httpRequest); sessionResponse.EnsureSuccessStatusCode(); var session = JsonConvert.DeserializeObject <CreateMessangerSessionResponse>(await sessionResponse.Content.ReadAsStringAsync()); string decryptedServerPublicKey = aes.Decrypt(decryptedAesKey, session.ServerPublicKey); string decryptedSessionId = aes.Decrypt(decryptedAesKey, session.SessionId); await userProvider.CreateSessionAsync(new Session() { ClientPrivateKey = rsaPair.privateKey, ServerPublicKey = decryptedServerPublicKey, ClientPublicKey = rsaPair.publicKey, UserId = UserId, SessionId = decryptedSessionId }); } else if (!string.IsNullOrEmpty(refreshToken) && strongKeyResponseMessage.StatusCode == HttpStatusCode.OK) { var strongKeyResponse = JsonConvert.DeserializeObject <GetStrongKeyResponse>( await strongKeyResponseMessage.Content.ReadAsStringAsync() ); var decryptedStrongKey = rsa.Decrypt(rsaPair.privateKey, strongKeyResponse.StrongKey); await userProvider.CreateStrongKeyAsync(UserId, decryptedStrongKey.FromUrlSafeBase64()); rsaPair = rsa.GenerateKeys(); var cryptedPublicKey = aes.Crypt(decryptedStrongKey, rsaPair.publicKey); var sessionRequest = new CreateMessangerSessionRequest() { PublicKey = cryptedPublicKey }; string jsonSessionRequest = JsonConvert.SerializeObject(sessionRequest); var sessionResponse = await authRequest.MakeRequestAsync <CreateMessangerSessionResponse>(ConfigurationManager.AppSettings.Get("devUrl") + Urls.CreateSessionUrl, HttpMethod.Post, jsonSessionRequest); string decryptedPublicKey = aes.Decrypt(decryptedStrongKey, sessionResponse.ServerPublicKey); string decryptedSessionId = aes.Decrypt(decryptedStrongKey, sessionResponse.SessionId); await userProvider.CreateSessionAsync(new Session() { ClientPrivateKey = rsaPair.privateKey, ClientPublicKey = rsaPair.publicKey, ServerPublicKey = decryptedPublicKey, UserId = UserId, SessionId = decryptedSessionId }); } }
public SportsController(RsaService rsaService, IUrlHelper urlHelper) { _rsaService = rsaService; _urlHelper = urlHelper; }
/// <summary> /// OnActionExecutionAsync /// </summary> /// <param name="context">ActionExecutingContext</param> /// <param name="next">ActionExecutionDelegate</param> private async Task <bool> OnBeforeActionAsync(ResourceExecutingContext context) { var request = context.HttpContext.Request; var err = string.Empty; bool isForwardRequestToApiAction = true; // Get request's custom headers var retryTimes = int.Parse(this.GetHeaderSingleValue(request.Headers, CustomHttpHeaderFactory.RetryTimes) ?? "0"); var requestCacheId = this.GetHeaderSingleValue(request.Headers, CustomHttpHeaderFactory.RequestCacheId); // Validate the Receiver value from header if (this.ValidateRequiredHeaders(requestCacheId, ref err)) { var encryptedPayload = string.Empty; #region Reading body from Http request this.logger.LogDebug($"{nameof(DecryptRequestFilter)}: start reading encrypted content from Http request..."); var initialBody = request.Body; try { request.EnableBuffering(); // Use request.EnableRewind() instead before ASP.NET Core 3 using (var reader = new StreamReader(request.Body)) { var content = await reader.ReadToEndAsync(); // Remove escapted character, eq. "\"xxxxx\"" => "xxxxx" encryptedPayload = JsonConvert.DeserializeObject <string>(content); } } catch (Exception ex) { string loadBodyErr = $"{nameof(DecryptRequestFilter)}: cannot read request body!"; this.logger.LogError(ex, loadBodyErr); isForwardRequestToApiAction = false; } finally { // (Optional) Render the original body, since it was flushed by StreamReader, // so that API action will be able to read body as well request.Body = initialBody; } this.logger.LogDebug($"{nameof(DecryptRequestFilter)}: end reading encrypted content from Http request."); #endregion #region Decrypt the encrypted content this.logger.LogDebug($"{nameof(DecryptRequestFilter)}: start decrypting content from Http request..."); if (string.IsNullOrEmpty(encryptedPayload)) { isForwardRequestToApiAction = false; } else { using (var rsa = new RsaService()) { try { #region Get public key var privateKey = await this.keyManager.GetPrivateKeyAsync(KeyTypeEnum.RSA); // To test retry policy... ////var privateKey = string.Empty; ////if (retryTimes > 0) //// privateKey = await this.keyManager.GetPrivateKeyAsync(KeyTypeEnum.RSA); ////else //// privateKey = (await this.keyManager.CreateDefaultAsymmetricKey(KeyTypeEnum.RSA, isIncludePrivateKey: true)).PrivateKey; // Set a incorrect private key to decrypt #endregion #region Decrypt and refactor to add escape charater for "\" // Get decrypted string var decryptedPayload = await rsa.DecryptAsync(privateKey, encryptedPayload); // Add escape charater for "\" var escaptedDecryptedPayload = decryptedPayload.Replace("\"", "\\\""); escaptedDecryptedPayload = $"\"{escaptedDecryptedPayload}\""; #endregion #region Convert the decrypted payload to byte array and bind to HttpRequest's body byte[] byteContent = Encoding.UTF8.GetBytes(escaptedDecryptedPayload); request.EnableBuffering(); // Use request.EnableRewind() instead before ASP.NET Core 3 request.Body.Position = 0; using (var reader = new StreamReader(request.Body)) { request.Body = new MemoryStream(byteContent); request.Headers.Remove("content-type"); request.Headers.Add("content-type", "application/json"); } #endregion } catch (Exception ex) when(ex is FormatException || ex is CryptographicException) { /* * FormatException occurs when the private key is incorrect RSA key * CryptographicException occuers when the data is incorrect encrypted */ var publicKey = await this.keyManager.GetPublicKeyAsync(KeyTypeEnum.RSA); this.logger.LogWarning(ex, $"Cannot decrypt with private key!"); context.Result = new EmptyResult(); context.HttpContext.Response.StatusCode = StatusCodes.Status422UnprocessableEntity; context.HttpContext.Response.Headers.Add(CustomHttpHeaderFactory.RequestCacheId, requestCacheId); context.HttpContext.Response.Headers.Add(CustomHttpHeaderFactory.PublicKey, publicKey); isForwardRequestToApiAction = false; } catch (Exception ex) { this.logger.LogError(ex, ex.Message); context.Result = new EmptyResult(); context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; isForwardRequestToApiAction = false; } } } this.logger.LogDebug($"{nameof(DecryptRequestFilter)}: end decrypting content from Http request."); #endregion } if (!string.IsNullOrEmpty(err)) { isForwardRequestToApiAction = false; await context.HttpContext.Response.WriteAsync(err); } return(isForwardRequestToApiAction); }
/// <summary> /// Create Retry policy hander instance /// </summary> /// <returns>PolicyBuilder of HttpResponseMessage</returns> public async Task <Polly.Retry.AsyncRetryPolicy <HttpResponseMessage> > CreateAsync(int maxRetryTimes = DefaultMaxRetryTimes) { var retryPolicy = Policy.HandleResult <HttpResponseMessage>(r => r.StatusCode.Equals(HttpStatusCode.UnprocessableEntity)) .RetryAsync(maxRetryTimes, async(exception, retryCount) => { this.logger.LogWarning($"The encrypted data was rejected, update public key and will retry {retryCount}/{maxRetryTimes}(times/total)..."); var request = exception.Result.RequestMessage; var response = exception.Result; // Public key response.Headers.TryGetValues(CustomHttpHeaderFactory.PublicKey, out IEnumerable <string> publicKeyValues); var correctPublicKey = publicKeyValues.FirstOrDefault(); // RequestICached response.Headers.TryGetValues(CustomHttpHeaderFactory.RequestCacheId, out IEnumerable <string> requestCacheIdValues); var requestCacheId = requestCacheIdValues.FirstOrDefault(); if (string.IsNullOrEmpty(correctPublicKey)) { this.logger.LogWarning($"The response does not have required header: \"{CustomHttpHeaderFactory.PublicKey}\". Stop retrying the request!"); throw new OperationCanceledException(); } else if (string.IsNullOrEmpty(requestCacheId)) { this.logger.LogWarning($"The response does not have required header: \"{CustomHttpHeaderFactory.RequestCacheId}\" on response. Stop retrying the request!"); throw new OperationCanceledException(); } else { #region Get the original request var cacheKey = requestCacheId; this.memoryCache.TryGetValue(cacheKey, out string jsonPayload); if (string.IsNullOrEmpty(jsonPayload)) { this.logger.LogWarning($"Lost the original request in MemoryCache (Key: {cacheKey}). Stop retrying the request!"); throw new OperationCanceledException(); } #endregion #region Encrypt the original request by the new public key using (var rsa = new RsaService()) { string encryptedPayload = await rsa.EncryptAsync(correctPublicKey, jsonPayload); // Replace the original content with the encrypted one var newContent = new System.Net.Http.StringContent($"\"{encryptedPayload}\"", Encoding.UTF8, "application/json"); request.Content = newContent; this.logger.LogDebug($"Successfully encrypting request."); } #endregion #region Retry times incremental request.Headers.Remove(CustomHttpHeaderFactory.RetryTimes); request.Headers.Add(CustomHttpHeaderFactory.RetryTimes, retryCount.ToString()); #endregion #region Update the correct public key with KeyManager var key = (await this.keyManager.GetKeyAsync(KeyTypeEnum.RSA)); key.PublicKey = correctPublicKey; await this.keyManager.SaveKeyAsync(key); this.logger.LogWarning($"Updated the correct public key. Now start retrying sending request."); #endregion } }); return(await Task.FromResult(retryPolicy)); }