// Helpers private async Task <EncryptedObject> AesEncryptAsync(byte[] data, SymmetricCryptoKey key) { var obj = new EncryptedObject { Key = await GetKeyForEncryptionAsync(key), Iv = await _cryptoFunctionService.RandomBytesAsync(16) }; obj.Data = await _cryptoFunctionService.AesEncryptAsync(data, obj.Iv, obj.Key.EncKey); if (obj.Key.MacKey != null) { var macData = new byte[obj.Iv.Length + obj.Data.Length]; Buffer.BlockCopy(obj.Iv, 0, macData, 0, obj.Iv.Length); Buffer.BlockCopy(obj.Data, 0, macData, obj.Iv.Length, obj.Data.Length); obj.Mac = await _cryptoFunctionService.HmacAsync(macData, obj.Key.MacKey, CryptoHashAlgorithm.Sha256); } return(obj); }
public byte[] EncryptToBytes(byte[] plainBytes, SymmetricCryptoKey key = null) { if (key == null) { key = EncKey ?? Key; } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (plainBytes == null) { throw new ArgumentNullException(nameof(plainBytes)); } return(Crypto.AesCbcEncryptToBytes(plainBytes, key)); }
private async Task <byte[]> AesDecryptToBytesAsync(EncryptionType encType, byte[] data, byte[] iv, byte[] mac, SymmetricCryptoKey key) { var keyForEnc = await GetKeyForEncryptionAsync(key); var theKey = ResolveLegacyKey(encType, keyForEnc); if (theKey.MacKey != null && mac == null) { // Mac required. return(null); } if (theKey.EncType != encType) { // encType unavailable. return(null); } // Compute mac if (theKey.MacKey != null && mac != null) { var macData = new byte[iv.Length + data.Length]; Buffer.BlockCopy(iv, 0, macData, 0, iv.Length); Buffer.BlockCopy(data, 0, macData, iv.Length, data.Length); var computedMac = await _cryptoFunctionService.HmacAsync(macData, theKey.MacKey, CryptoHashAlgorithm.Sha256); if (computedMac == null) { return(null); } var macsMatch = await _cryptoFunctionService.CompareAsync(mac, computedMac); if (!macsMatch) { // Mac failed return(null); } } return(await _cryptoFunctionService.AesDecryptAsync(data, iv, theKey.EncKey)); }
public async Task <byte[]> DecryptFromBytesAsync(byte[] encBytes, SymmetricCryptoKey key) { if (encBytes == null) { throw new Exception("no encBytes."); } var encType = (EncryptionType)encBytes[0]; byte[] ctBytes = null; byte[] ivBytes = null; byte[] macBytes = null; switch (encType) { case EncryptionType.AesCbc128_HmacSha256_B64: case EncryptionType.AesCbc256_HmacSha256_B64: if (encBytes.Length < 49) // 1 + 16 + 32 + ctLength { return(null); } ivBytes = new ArraySegment <byte>(encBytes, 1, 16).ToArray(); macBytes = new ArraySegment <byte>(encBytes, 17, 32).ToArray(); ctBytes = new ArraySegment <byte>(encBytes, 49, encBytes.Length - 49).ToArray(); break; case EncryptionType.AesCbc256_B64: if (encBytes.Length < 17) // 1 + 16 + ctLength { return(null); } ivBytes = new ArraySegment <byte>(encBytes, 1, 16).ToArray(); ctBytes = new ArraySegment <byte>(encBytes, 17, encBytes.Length - 17).ToArray(); break; default: return(null); } return(await AesDecryptToBytesAsync(encType, ctBytes, ivBytes, macBytes, key)); }
public async Task <byte[]> DownloadAndDecryptAttachmentAsync(string url, CipherString key, string orgId = null) { using (var client = new HttpClient()) { try { var response = await client.GetAsync(new Uri(url)).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { return(null); } var data = await response.Content.ReadAsByteArrayAsync(); if (data == null) { return(null); } SymmetricCryptoKey regularKey = !string.IsNullOrWhiteSpace(orgId) ? _cryptoService.GetOrgKey(orgId) : null; SymmetricCryptoKey dataKey = null; if (key != null) { var decDataKey = _cryptoService.DecryptToBytes(key, regularKey); dataKey = new SymmetricCryptoKey(decDataKey); } else { dataKey = regularKey; } return(_cryptoService.DecryptToBytes(data, dataKey)); } catch { return(null); } } }
public LoginTwoFactorPage(string email, FullLoginResult result, TwoFactorProviderType?type = null) : base(updateActivity: false) { _deviceInfoService = Resolver.Resolve <IDeviceInfoService>(); _email = email; _result = result; _masterPasswordHash = result.MasterPasswordHash; _key = result.Key; _providers = result.TwoFactorProviders; _providerType = type ?? GetDefaultProvider(); _authService = Resolver.Resolve <IAuthService>(); _userDialogs = Resolver.Resolve <IUserDialogs>(); _syncService = Resolver.Resolve <ISyncService>(); _googleAnalyticsService = Resolver.Resolve <IGoogleAnalyticsService>(); _twoFactorApiRepository = Resolver.Resolve <ITwoFactorApiRepository>(); _pushNotification = Resolver.Resolve <IPushNotification>(); Init(); }
private async Task <Tuple <SymmetricCryptoKey, EncString> > BuildEncKeyAsync(SymmetricCryptoKey key, byte[] encKey) { EncString encKeyEnc = null; if (key.Key.Length == 32) { var newKey = await StretchKeyAsync(key); encKeyEnc = await EncryptAsync(encKey, newKey); } else if (key.Key.Length == 64) { encKeyEnc = await EncryptAsync(encKey, key); } else { throw new Exception("Invalid key size."); } return(new Tuple <SymmetricCryptoKey, EncString>(new SymmetricCryptoKey(encKey), encKeyEnc)); }
public static CipherString AesCbcEncrypt(byte[] plainBytes, SymmetricCryptoKey key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (plainBytes == null) { throw new ArgumentNullException(nameof(plainBytes)); } var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); var cryptoKey = provider.CreateSymmetricKey(key.EncKey); var iv = RandomBytes(provider.BlockLength); var encryptedBytes = WinRTCrypto.CryptographicEngine.Encrypt(cryptoKey, plainBytes, iv); var mac = key.MacKey != null?ComputeMacBase64(encryptedBytes, iv, key.MacKey) : null; return(new CipherString(key.EncryptionType, Convert.ToBase64String(iv), Convert.ToBase64String(encryptedBytes), mac)); }
public async Task <byte[]> EncryptToBytesAsync(byte[] plainValue, SymmetricCryptoKey key = null) { var encValue = await AesEncryptAsync(plainValue, key); var macLen = 0; if (encValue.Mac != null) { macLen = encValue.Mac.Length; } var encBytes = new byte[1 + encValue.Iv.Length + macLen + encValue.Data.Length]; Buffer.BlockCopy(new byte[] { (byte)encValue.Key.EncType }, 0, encBytes, 0, 1); Buffer.BlockCopy(encValue.Iv, 0, encBytes, 1, encValue.Iv.Length); if (encValue.Mac != null) { Buffer.BlockCopy(encValue.Mac, 0, encBytes, 1 + encValue.Iv.Length, encValue.Mac.Length); } Buffer.BlockCopy(encValue.Data, 0, encBytes, 1 + encValue.Iv.Length + macLen, encValue.Data.Length); return(encBytes); }
private async Task ProcessLoginSuccessAsync(SymmetricCryptoKey key, TokenResponse response) { if (response.Key != null) { _cryptoService.SetEncKey(new CipherString(response.Key)); } if (response.PrivateKey != null) { _cryptoService.SetPrivateKey(new CipherString(response.PrivateKey)); } _cryptoService.Key = key; _tokenService.Token = response.AccessToken; _tokenService.RefreshToken = response.RefreshToken; UserId = _tokenService.TokenUserId; Email = _tokenService.TokenEmail; _settings.AddOrUpdateValue(Constants.LastLoginEmail, Email); _appSettingsService.FailedPinAttempts = 0; _appSettingsService.OrganizationGivesPremium = false; if (response.PrivateKey != null) { var profile = await _accountsApiRepository.GetProfileAsync(); if (profile.Succeeded) { _cryptoService.SetOrgKeys(profile.Result); _appSettingsService.OrganizationGivesPremium = profile.Result?.Organizations?.Any(o => o.UsersGetPremium && o.Enabled) ?? false; } } if (!string.IsNullOrWhiteSpace(response.TwoFactorToken)) { _tokenService.SetTwoFactorToken(_tokenService.TokenEmail, response.TwoFactorToken); } }
public LoginTwoFactorPage(string email, FullLoginResult result, TwoFactorProviderType?type = null) : base(updateActivity: false, requireAuth: false) { _duoOrgTitle = $"Duo ({AppResources.Organization})"; _deviceInfoService = Resolver.Resolve <IDeviceInfoService>(); _email = email; _result = result; _masterPasswordHash = result.MasterPasswordHash; _key = result.Key; _providers = result.TwoFactorProviders; _providerType = type ?? GetDefaultProvider(); _deviceActionService = Resolver.Resolve <IDeviceActionService>(); _authService = Resolver.Resolve <IAuthService>(); _syncService = Resolver.Resolve <ISyncService>(); _appSettingsService = Resolver.Resolve <IAppSettingsService>(); _googleAnalyticsService = Resolver.Resolve <IGoogleAnalyticsService>(); _twoFactorApiRepository = Resolver.Resolve <ITwoFactorApiRepository>(); _pushNotification = Resolver.Resolve <IPushNotificationService>(); Init(); }
private async Task ProcessLoginSuccessAsync(SymmetricCryptoKey key, TokenResponse response) { if (response.PrivateKey != null) { _cryptoService.SetPrivateKey(new CipherString(response.PrivateKey)); } _cryptoService.Key = key; _tokenService.Token = response.AccessToken; _tokenService.RefreshToken = response.RefreshToken; UserId = _tokenService.TokenUserId; Email = _tokenService.TokenEmail; _settings.AddOrUpdateValue(Constants.LastLoginEmail, Email); if (response.PrivateKey != null) { var profile = await _accountsApiRepository.GetProfileAsync(); if (profile.Succeeded) { _cryptoService.SetOrgKeys(profile.Result); } } }
public async Task <Tuple <SymmetricCryptoKey, CipherString> > RemakeEncKeyAsync(SymmetricCryptoKey key) { var encKey = await GetEncKeyAsync(); return(await BuildEncKeyAsync(key, encKey.Key)); }
public async Task ClearKeyAsync() { _key = _legacyEtmKey = null; await _secureStorageService.RemoveAsync(Keys_Key); }
public async Task <Tuple <SymmetricCryptoKey, CipherString> > MakeEncKeyAsync(SymmetricCryptoKey key) { var theKey = await GetKeyForEncryptionAsync(key); var encKey = await _cryptoFunctionService.RandomBytesAsync(64); return(await BuildEncKeyAsync(theKey, encKey)); }
private async Task <AuthResult> LogInHelperAsync(string email, string hashedPassword, string code, string codeVerifier, string redirectUrl, SymmetricCryptoKey key, TwoFactorProviderType?twoFactorProvider = null, string twoFactorToken = null, bool?remember = null) { var storedTwoFactorToken = await _tokenService.GetTwoFactorTokenAsync(email); var appId = await _appIdService.GetAppIdAsync(); var deviceRequest = new DeviceRequest(appId, _platformUtilsService); string[] emailPassword; string[] codeCodeVerifier; if (email != null && hashedPassword != null) { emailPassword = new[] { email, hashedPassword }; } else { emailPassword = null; } if (code != null && codeVerifier != null && redirectUrl != null) { codeCodeVerifier = new[] { code, codeVerifier, redirectUrl }; } else { codeCodeVerifier = null; } TokenRequest request; if (twoFactorToken != null && twoFactorProvider != null) { request = new TokenRequest(emailPassword, codeCodeVerifier, twoFactorProvider, twoFactorToken, remember, deviceRequest); } else if (storedTwoFactorToken != null) { request = new TokenRequest(emailPassword, codeCodeVerifier, TwoFactorProviderType.Remember, storedTwoFactorToken, false, deviceRequest); } else { request = new TokenRequest(emailPassword, codeCodeVerifier, null, null, false, deviceRequest); } var response = await _apiService.PostIdentityTokenAsync(request); ClearState(); var result = new AuthResult { TwoFactor = response.Item2 != null }; if (result.TwoFactor) { // Two factor required. var twoFactorResponse = response.Item2; Email = email; MasterPasswordHash = hashedPassword; Code = code; CodeVerifier = codeVerifier; SsoRedirectUrl = redirectUrl; _key = _setCryptoKeys ? key : null; TwoFactorProvidersData = twoFactorResponse.TwoFactorProviders2; result.TwoFactorProviders = twoFactorResponse.TwoFactorProviders2; return(result); } var tokenResponse = response.Item1; result.ResetMasterPassword = tokenResponse.ResetMasterPassword; if (tokenResponse.TwoFactorToken != null) { await _tokenService.SetTwoFactorTokenAsync(tokenResponse.TwoFactorToken, email); } await _tokenService.SetTokensAsync(tokenResponse.AccessToken, tokenResponse.RefreshToken); await _userService.SetInformationAsync(_tokenService.GetUserId(), _tokenService.GetEmail(), tokenResponse.Kdf, tokenResponse.KdfIterations); if (_setCryptoKeys) { await _cryptoService.SetKeyAsync(key); await _cryptoService.SetKeyHashAsync(hashedPassword); await _cryptoService.SetEncKeyAsync(tokenResponse.Key); // User doesn't have a key pair yet (old account), let's generate one for them. if (tokenResponse.PrivateKey == null) { try { var keyPair = await _cryptoService.MakeKeyPairAsync(); await _apiService.PostAccountKeysAsync(new KeysRequest { PublicKey = keyPair.Item1, EncryptedPrivateKey = keyPair.Item2.EncryptedString }); tokenResponse.PrivateKey = keyPair.Item2.EncryptedString; } catch { } } await _cryptoService.SetEncPrivateKeyAsync(tokenResponse.PrivateKey); } _vaultTimeoutService.BiometricLocked = false; _messagingService.Send("loggedIn"); return(result); }
public Task <SymmetricCryptoKey> GetEncKeyAsync(SymmetricCryptoKey key = null) { if (_encKey != null) { return(Task.FromResult(_encKey)); } if (_getEncKeysTask != null && !_getEncKeysTask.IsCompleted && !_getEncKeysTask.IsFaulted) { return(_getEncKeysTask); } async Task <SymmetricCryptoKey> doTask() { try { var encKey = await _storageService.GetAsync <string>(Keys_EncKey); if (encKey == null) { return(null); } if (key == null) { key = await GetKeyAsync(); } if (key == null) { return(null); } byte[] decEncKey = null; var encKeyCipher = new CipherString(encKey); if (encKeyCipher.EncryptionType == EncryptionType.AesCbc256_B64) { decEncKey = await DecryptToBytesAsync(encKeyCipher, key); } else if (encKeyCipher.EncryptionType == EncryptionType.AesCbc256_HmacSha256_B64) { var newKey = await StretchKeyAsync(key); decEncKey = await DecryptToBytesAsync(encKeyCipher, newKey); } else { throw new Exception("Unsupported encKey type."); } if (decEncKey == null) { return(null); } _encKey = new SymmetricCryptoKey(decEncKey); return(_encKey); } finally { _getEncKeysTask = null; } } _getEncKeysTask = doTask(); return(_getEncKeysTask); }
private void ProtocolV4(Stream stream, CertificateStore clientCredentials, Certificate[] trustedRootCertificates, ISecureChannelSecurityManager manager, string preSharedKey, SecureChannelCryptoOptionFlags supportedOptions) { #region 1. hello handshake //send client hello SecureChannelPacket.Hello clientHello = new SecureChannelPacket.Hello(BinaryID.GenerateRandomID256(), supportedOptions); SecureChannelPacket.WritePacket(stream, clientHello); //read server hello SecureChannelPacket.Hello serverHello = (new SecureChannelPacket(stream)).GetHello(); //read selected crypto option _selectedCryptoOption = supportedOptions & serverHello.CryptoOptions; if (_selectedCryptoOption == SecureChannelCryptoOptionFlags.None) throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); #endregion #region 2. key exchange //read server key exchange data SecureChannelPacket.KeyExchange serverKeyExchange = (new SecureChannelPacket(stream)).GetKeyExchange(); SymmetricEncryptionAlgorithm encAlgo; string hashAlgo; KeyAgreement keyAgreement; switch (_selectedCryptoOption) { case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256: encAlgo = SymmetricEncryptionAlgorithm.Rijndael; hashAlgo = "SHA256"; keyAgreement = new DiffieHellman(DiffieHellmanGroupType.RFC3526, 2048, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256); break; case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256: encAlgo = SymmetricEncryptionAlgorithm.Rijndael; hashAlgo = "SHA256"; keyAgreement = new TechnitiumLibrary.Security.Cryptography.ECDiffieHellman(256, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } //send client key exchange data SecureChannelPacket.KeyExchange clientKeyExchange = new SecureChannelPacket.KeyExchange(keyAgreement.GetPublicKeyXML(), clientCredentials.PrivateKey, hashAlgo); SecureChannelPacket.WritePacket(stream, clientKeyExchange); //generate master key byte[] masterKey = GenerateMasterKey(clientHello, serverHello, _preSharedKey, keyAgreement, serverKeyExchange.PublicKeyXML); //verify master key using HMAC authentication { SecureChannelPacket.Authentication clientAuthentication = new SecureChannelPacket.Authentication(serverHello, masterKey); SecureChannelPacket.WritePacket(stream, clientAuthentication); SecureChannelPacket.Authentication serverAuthentication = (new SecureChannelPacket(stream)).GetAuthentication(); if (!serverAuthentication.IsValid(clientHello, masterKey)) throw new SecureChannelException(SecureChannelCode.ProtocolAuthenticationFailed, _remotePeerEP, _remotePeerCert); } //enable channel encryption switch (encAlgo) { case SymmetricEncryptionAlgorithm.Rijndael: //using MD5 for generating AES IV of 128bit block size HashAlgorithm md5Hash = HashAlgorithm.Create("MD5"); byte[] eIV = md5Hash.ComputeHash(clientHello.Nonce.ID); byte[] dIV = md5Hash.ComputeHash(serverHello.Nonce.ID); //create encryption and decryption objects SymmetricCryptoKey encryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, eIV, PaddingMode.None); SymmetricCryptoKey decryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, dIV, PaddingMode.None); //enable encryption EnableEncryption(stream, encryptionKey, decryptionKey, new HMACSHA256(masterKey), new HMACSHA256(masterKey)); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } //channel encryption is ON! #endregion #region 3. exchange & verify certificates & signatures if (!_reNegotiating) { //send client certificate SecureChannelPacket.WritePacket(this, clientCredentials.Certificate); //read server certificate _remotePeerCert = (new SecureChannelPacket(this)).GetCertificate(); //verify server certificate try { _remotePeerCert.Verify(trustedRootCertificates); } catch (Exception ex) { throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificate, _remotePeerEP, _remotePeerCert, "Invalid remote certificate.", ex); } } //verify key exchange signature switch (_selectedCryptoOption) { case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256: case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256: if (_remotePeerCert.PublicKeyEncryptionAlgorithm != AsymmetricEncryptionAlgorithm.RSA) throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificateAlgorithm, _remotePeerEP, _remotePeerCert); if (!serverKeyExchange.IsSignatureValid(_remotePeerCert, "SHA256")) throw new SecureChannelException(SecureChannelCode.InvalidRemoteKeyExchangeSignature, _remotePeerEP, _remotePeerCert); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } if ((manager != null) && !manager.ProceedConnection(_remotePeerCert)) throw new SecureChannelException(SecureChannelCode.SecurityManagerDeclinedAccess, _remotePeerEP, _remotePeerCert, "Security manager declined access."); #endregion }
private void ProtocolV4(Stream stream) { #region 1. hello handshake //read client hello SecureChannelPacket.Hello clientHello = (new SecureChannelPacket(stream)).GetHello(); //select crypto option _selectedCryptoOption = _supportedOptions & clientHello.CryptoOptions; if (_selectedCryptoOption == SecureChannelCryptoOptionFlags.None) { throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } else if ((_selectedCryptoOption & SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256) > 0) { _selectedCryptoOption = SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256; } else if ((_selectedCryptoOption & SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256) > 0) { _selectedCryptoOption = SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256; } else { throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } //send server hello SecureChannelPacket.Hello serverHello = new SecureChannelPacket.Hello(BinaryID.GenerateRandomID256(), _selectedCryptoOption); SecureChannelPacket.WritePacket(stream, serverHello); #endregion #region 2. key exchange SymmetricEncryptionAlgorithm encAlgo; string hashAlgo; KeyAgreement keyAgreement; switch (_selectedCryptoOption) { case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256: encAlgo = SymmetricEncryptionAlgorithm.Rijndael; hashAlgo = "SHA256"; keyAgreement = new DiffieHellman(DiffieHellmanGroupType.RFC3526, 2048, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256); break; case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256: encAlgo = SymmetricEncryptionAlgorithm.Rijndael; hashAlgo = "SHA256"; keyAgreement = new TechnitiumLibrary.Security.Cryptography.ECDiffieHellman(256, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } //send server key exchange data SecureChannelPacket.KeyExchange serverKeyExchange = new SecureChannelPacket.KeyExchange(keyAgreement.GetPublicKey(), _serverCredentials.PrivateKey, hashAlgo); SecureChannelPacket.WritePacket(stream, serverKeyExchange); //read client key exchange data SecureChannelPacket.KeyExchange clientKeyExchange = (new SecureChannelPacket(stream)).GetKeyExchange(); //generate master key byte[] masterKey = GenerateMasterKey(clientHello, serverHello, _preSharedKey, keyAgreement, clientKeyExchange.PublicKey); //verify master key using HMAC authentication { SecureChannelPacket.Authentication clientAuthentication = (new SecureChannelPacket(stream)).GetAuthentication(); if (!clientAuthentication.IsValid(serverHello, masterKey)) { throw new SecureChannelException(SecureChannelCode.ProtocolAuthenticationFailed, _remotePeerEP, _remotePeerCert); } SecureChannelPacket.Authentication serverAuthentication = new SecureChannelPacket.Authentication(clientHello, masterKey); SecureChannelPacket.WritePacket(stream, serverAuthentication); } //enable channel encryption switch (encAlgo) { case SymmetricEncryptionAlgorithm.Rijndael: //using MD5 for generating AES IV of 128bit block size HashAlgorithm md5Hash = HashAlgorithm.Create("MD5"); byte[] eIV = md5Hash.ComputeHash(serverHello.Nonce.ID); byte[] dIV = md5Hash.ComputeHash(clientHello.Nonce.ID); //create encryption and decryption objects SymmetricCryptoKey encryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, eIV, PaddingMode.None); SymmetricCryptoKey decryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, dIV, PaddingMode.None); //enable encryption EnableEncryption(stream, encryptionKey, decryptionKey, new HMACSHA256(masterKey), new HMACSHA256(masterKey)); break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } //channel encryption is ON! #endregion #region 3. exchange & verify certificates & signatures if (!IsReNegotiating()) { //read client certificate _remotePeerCert = (new SecureChannelPacket(this)).GetCertificate(); //verify client certificate try { _remotePeerCert.Verify(_trustedRootCertificates); } catch (Exception ex) { throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificate, _remotePeerEP, _remotePeerCert, "Invalid remote certificate.", ex); } } //verify key exchange signature switch (_selectedCryptoOption) { case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256: case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256: if (_remotePeerCert.PublicKeyEncryptionAlgorithm != AsymmetricEncryptionAlgorithm.RSA) { throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificateAlgorithm, _remotePeerEP, _remotePeerCert); } if (!clientKeyExchange.IsSignatureValid(_remotePeerCert, "SHA256")) { throw new SecureChannelException(SecureChannelCode.InvalidRemoteKeyExchangeSignature, _remotePeerEP, _remotePeerCert); } break; default: throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert); } if ((_manager != null) && !_manager.ProceedConnection(_remotePeerCert)) { throw new SecureChannelException(SecureChannelCode.SecurityManagerDeclinedAccess, _remotePeerEP, _remotePeerCert, "Security manager declined access."); } //send server certificate if (!IsReNegotiating()) { SecureChannelPacket.WritePacket(this, _serverCredentials.Certificate); } #endregion }
public string HashPasswordBase64(SymmetricCryptoKey key, string password) { var hash = HashPassword(key, password); return(Convert.ToBase64String(hash)); }
private async Task <AuthResult> LogInHelperAsync(string email, string hashedPassword, string localHashedPassword, string code, string codeVerifier, string redirectUrl, SymmetricCryptoKey key, TwoFactorProviderType?twoFactorProvider = null, string twoFactorToken = null, bool?remember = null, string captchaToken = null, string orgId = null) { var storedTwoFactorToken = await _tokenService.GetTwoFactorTokenAsync(email); var appId = await _appIdService.GetAppIdAsync(); var deviceRequest = new DeviceRequest(appId, _platformUtilsService); string[] emailPassword; string[] codeCodeVerifier; if (email != null && hashedPassword != null) { emailPassword = new[] { email, hashedPassword }; } else { emailPassword = null; } if (code != null && codeVerifier != null && redirectUrl != null) { codeCodeVerifier = new[] { code, codeVerifier, redirectUrl }; } else { codeCodeVerifier = null; } TokenRequest request; if (twoFactorToken != null && twoFactorProvider != null) { request = new TokenRequest(emailPassword, codeCodeVerifier, twoFactorProvider, twoFactorToken, remember, captchaToken, deviceRequest); } else if (storedTwoFactorToken != null) { request = new TokenRequest(emailPassword, codeCodeVerifier, TwoFactorProviderType.Remember, storedTwoFactorToken, false, captchaToken, deviceRequest); } else { request = new TokenRequest(emailPassword, codeCodeVerifier, null, null, false, captchaToken, deviceRequest); } var response = await _apiService.PostIdentityTokenAsync(request); ClearState(); var result = new AuthResult { TwoFactor = response.TwoFactorNeeded, CaptchaSiteKey = response.CaptchaResponse?.SiteKey }; if (result.CaptchaNeeded) { return(result); } if (result.TwoFactor) { // Two factor required. Email = email; MasterPasswordHash = hashedPassword; LocalMasterPasswordHash = localHashedPassword; Code = code; CodeVerifier = codeVerifier; SsoRedirectUrl = redirectUrl; _key = _setCryptoKeys ? key : null; TwoFactorProvidersData = response.TwoFactorResponse.TwoFactorProviders2; result.TwoFactorProviders = response.TwoFactorResponse.TwoFactorProviders2; CaptchaToken = response.TwoFactorResponse.CaptchaToken; return(result); } var tokenResponse = response.TokenResponse; result.ResetMasterPassword = tokenResponse.ResetMasterPassword; result.ForcePasswordReset = tokenResponse.ForcePasswordReset; if (tokenResponse.TwoFactorToken != null) { await _tokenService.SetTwoFactorTokenAsync(tokenResponse.TwoFactorToken, email); } await _tokenService.SetAccessTokenAsync(tokenResponse.AccessToken, true); await _stateService.AddAccountAsync( new Account( new Account.AccountProfile() { UserId = _tokenService.GetUserId(), Email = _tokenService.GetEmail(), Name = _tokenService.GetName(), KdfType = tokenResponse.Kdf, KdfIterations = tokenResponse.KdfIterations, HasPremiumPersonally = _tokenService.GetPremium(), }, new Account.AccountTokens() { AccessToken = tokenResponse.AccessToken, RefreshToken = tokenResponse.RefreshToken, } ) ); _messagingService.Send("accountAdded"); if (_setCryptoKeys) { if (key != null) { await _cryptoService.SetKeyAsync(key); } if (localHashedPassword != null) { await _cryptoService.SetKeyHashAsync(localHashedPassword); } if (code == null || tokenResponse.Key != null) { if (tokenResponse.KeyConnectorUrl != null) { await _keyConnectorService.GetAndSetKey(tokenResponse.KeyConnectorUrl); } await _cryptoService.SetEncKeyAsync(tokenResponse.Key); // User doesn't have a key pair yet (old account), let's generate one for them. if (tokenResponse.PrivateKey == null) { try { var keyPair = await _cryptoService.MakeKeyPairAsync(); await _apiService.PostAccountKeysAsync(new KeysRequest { PublicKey = keyPair.Item1, EncryptedPrivateKey = keyPair.Item2.EncryptedString }); tokenResponse.PrivateKey = keyPair.Item2.EncryptedString; } catch { } } await _cryptoService.SetEncPrivateKeyAsync(tokenResponse.PrivateKey); } else if (tokenResponse.KeyConnectorUrl != null) { // SSO Key Connector Onboarding var password = await _cryptoFunctionService.RandomBytesAsync(64); var k = await _cryptoService.MakeKeyAsync(Convert.ToBase64String(password), _tokenService.GetEmail(), tokenResponse.Kdf, tokenResponse.KdfIterations); var keyConnectorRequest = new KeyConnectorUserKeyRequest(k.EncKeyB64); await _cryptoService.SetKeyAsync(k); var encKey = await _cryptoService.MakeEncKeyAsync(k); await _cryptoService.SetEncKeyAsync(encKey.Item2.EncryptedString); var keyPair = await _cryptoService.MakeKeyPairAsync(); try { await _apiService.PostUserKeyToKeyConnector(tokenResponse.KeyConnectorUrl, keyConnectorRequest); } catch (Exception e) { throw new Exception("Unable to reach Key Connector", e); } var keys = new KeysRequest { PublicKey = keyPair.Item1, EncryptedPrivateKey = keyPair.Item2.EncryptedString }; var setPasswordRequest = new SetKeyConnectorKeyRequest( encKey.Item2.EncryptedString, keys, tokenResponse.Kdf, tokenResponse.KdfIterations, orgId ); await _apiService.PostSetKeyConnectorKey(setPasswordRequest); } } await _stateService.SetBiometricLockedAsync(false); _messagingService.Send("loggedIn"); return(result); }
public static SymmetricCryptoKey CreateSymmetricCryptoKey(int cryptoKeyId, string bucket, string handle, global::System.DateTime expirationUtc, byte[] secret) { SymmetricCryptoKey symmetricCryptoKey = new SymmetricCryptoKey(); symmetricCryptoKey.CryptoKeyId = cryptoKeyId; symmetricCryptoKey.Bucket = bucket; symmetricCryptoKey.Handle = handle; symmetricCryptoKey.ExpirationUtc = expirationUtc; symmetricCryptoKey.Secret = secret; return symmetricCryptoKey; }
public CipherString MakeEncKey(SymmetricCryptoKey key) { var bytes = Crypto.RandomBytes(512 / 8); return(Encrypt(bytes, key)); }
public async Task WhoAmI() { var jso = new JsonSerializerOptions { WriteIndented = true, }; Console.WriteLine("Is Authenticated....: {0}", await _userService.IsAuthenticatedAsync()); Console.WriteLine("User ID.............: {0}", await _userService.GetUserIdAsync()); Console.WriteLine("Acct Rev Date.......: {0}", CoreHelpers.Epoc.AddMilliseconds(await _apiService.GetAccountRevisionDateAsync())); var sync = await _apiService.GetSyncAsync(); await _cryptoService.SetOrgKeysAsync(sync.Profile.Organizations); Console.WriteLine(); Console.WriteLine("Profile:"); Console.WriteLine(" ID........................: {0}", sync.Profile.Id); Console.WriteLine(" Name......................: {0}", sync.Profile.Name); Console.WriteLine(" Email.....................: {0}", sync.Profile.Email); Console.WriteLine(" Email Verified............: {0}", sync.Profile.EmailVerified); Console.WriteLine(" Premium...................: {0}", sync.Profile.Premium); //Console.WriteLine(" Master Password Hint......: {0}", sync.Profile.MasterPasswordHint); //Console.WriteLine(" Security Stamp............: {0}", sync.Profile.SecurityStamp); //Console.WriteLine(" Key.......................: {0}", sync.Profile.Key); //Console.WriteLine(" Private Key...............: {0}", sync.Profile.PrivateKey); Console.WriteLine(); Console.WriteLine("Orgs:"); string orgKeyS = null; SymmetricCryptoKey orgKey = null; foreach (var o in sync.Profile.Organizations) { Console.WriteLine(" * {0} = {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", o.Id, o.Name, o.Enabled, o.Type, o.Status, o.MaxCollections, o.Status, o.Seats, o.Key); orgKeyS = o.Key; //orgKey = new SymmetricCryptoKey(await _cryptoService.DecryptToBytesAsync(new CipherString(o.Key))); } Console.WriteLine(); Console.WriteLine("Folders:"); foreach (var f in sync.Folders) { var nm = await _cryptoService.DecryptToUtf8Async(new CipherString(f.Name)); Console.WriteLine(" * {0} = {1} = {2}", f.Id, f.Name, nm); } Console.WriteLine(); Console.WriteLine("Collections:"); foreach (var c in sync.Collections) { //var nm = await _cryptoService.DecryptToUtf8Async(new CipherString(c.Name), orgKey); var nm = await _cryptoService.DecryptToUtf8Async(new CipherString(c.Name)); Console.WriteLine(" * {0} = {1}, {2}, {3}, {4}, {5}", c.Id, c.Name, nm, c.OrganizationId, c.ReadOnly, c.ExternalId); } Console.WriteLine(); Console.WriteLine("Ciphers:"); foreach (var c in sync.Ciphers) { var nm = await _cryptoService.DecryptToUtf8Async(new CipherString(c.Name)); var us = c.Login == null ? "" : await _cryptoService.DecryptToUtf8Async(new CipherString(c.Login.Username)); var pw = c.Login == null ? "" : await _cryptoService.DecryptToUtf8Async(new CipherString(c.Login.Password)); //var nt = await _cryptoService.DecryptToUtf8Async(new CipherString(c.Notes)); Console.WriteLine(" * {0}, {1}, {2}, {3}", JsonSerializer.Serialize(c, jso), nm, us, pw); } }
public void AddToSymmetricCryptoKeys(SymmetricCryptoKey symmetricCryptoKey) { base.AddObject("SymmetricCryptoKeys", symmetricCryptoKey); }
public async Task <string> DecryptToUtf8Async(EncString encString, SymmetricCryptoKey key = null) { return(await AesDecryptToUtf8Async(encString.EncryptionType, encString.Data, encString.Iv, encString.Mac, key)); }
protected void EnableEncryption(Stream inputStream, SymmetricCryptoKey encryptionKey, SymmetricCryptoKey decryptionKey, HMAC authHMACEncrypt, HMAC authHMACDecrypt) { //create reader and writer objects _encryptionKey = encryptionKey; _cryptoEncryptor = encryptionKey.GetEncryptor(); _cryptoDecryptor = decryptionKey.GetDecryptor(); //init variables _baseStream = inputStream; _blockSizeBytes = encryptionKey.BlockSize / 8; _writeBufferPadding = new byte[_blockSizeBytes]; _authHMACEncrypt = authHMACEncrypt; _authHMACDecrypt = authHMACDecrypt; _authHMACSize = authHMACEncrypt.HashSize / 8; _bytesSent = 0; _connectedOn = DateTime.UtcNow; if (_reNegotiationTimer == null) { if ((_reNegotiateOnBytesSent > 0) || (_reNegotiateAfterSeconds > 0)) _reNegotiationTimer = new Timer(ReNegotiationTimerCallback, null, _reNegotiationTimerInterval, Timeout.Infinite); } }
private static Tuple <EncryptionType, byte[], byte[], byte[]> AesCbcEncryptToParts(byte[] plainBytes, SymmetricCryptoKey key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (plainBytes == null) { throw new ArgumentNullException(nameof(plainBytes)); } var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); var cryptoKey = provider.CreateSymmetricKey(key.EncKey); var iv = RandomBytes(provider.BlockLength); var ct = WinRTCrypto.CryptographicEngine.Encrypt(cryptoKey, plainBytes, iv); var mac = key.MacKey != null?ComputeMac(ct, iv, key.MacKey) : null; return(new Tuple <EncryptionType, byte[], byte[], byte[]>(key.EncryptionType, iv, mac, ct)); }
public async Task <string> DecryptToUtf8Async(CipherString cipherString, SymmetricCryptoKey key = null) { return(await AesDecryptToUtf8Async(cipherString.EncryptionType, cipherString.Data, cipherString.Iv, cipherString.Mac, key)); }
public static byte[] AesCbcDecrypt(EncryptionType type, byte[] ct, byte[] iv, byte[] mac, SymmetricCryptoKey key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (ct == null) { throw new ArgumentNullException(nameof(ct)); } if (iv == null) { throw new ArgumentNullException(nameof(iv)); } if (key.MacKey != null && mac == null) { throw new ArgumentNullException(nameof(mac)); } if (key.EncryptionType != type) { throw new InvalidOperationException(nameof(type)); } if (key.MacKey != null && mac != null) { var computedMacBytes = ComputeMac(ct, iv, key.MacKey); if (!MacsEqual(computedMacBytes, mac)) { throw new InvalidOperationException("MAC failed."); } } var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); var cryptoKey = provider.CreateSymmetricKey(key.EncKey); var decryptedBytes = WinRTCrypto.CryptographicEngine.Decrypt(cryptoKey, ct, iv); return(decryptedBytes); }
protected void EnableEncryption(Stream inputStream, SymmetricCryptoKey encryptionKey, SymmetricCryptoKey decryptionKey, HMAC authHMACEncrypt, HMAC authHMACDecrypt) { //create reader and writer objects _encryptionKey = encryptionKey; _cryptoEncryptor = encryptionKey.GetEncryptor(); _cryptoDecryptor = decryptionKey.GetDecryptor(); //init variables _baseStream = inputStream; _blockSizeBytes = encryptionKey.BlockSize / 8; _writeBufferPadding = new byte[_blockSizeBytes]; _authHMACEncrypt = authHMACEncrypt; _authHMACDecrypt = authHMACDecrypt; _authHMACSize = authHMACEncrypt.HashSize / 8; _bytesSent = 0; _connectedOn = DateTime.UtcNow; if (_reNegotiationTimer == null) { if ((_reNegotiateOnBytesSent > 0) || (_reNegotiateAfterSeconds > 0)) { _reNegotiationTimer = new Timer(ReNegotiationTimerCallback, null, _reNegotiationTimerInterval, Timeout.Infinite); } } }
private async Task <AuthResult> LogInHelperAsync(string email, string hashedPassword, SymmetricCryptoKey key, TwoFactorProviderType?twoFactorProvider = null, string twoFactorToken = null, bool?remember = null) { var storedTwoFactorToken = await _tokenService.GetTwoFactorTokenAsync(email); var appId = await _appIdService.GetAppIdAsync(); var deviceRequest = new DeviceRequest(appId, _platformUtilsService); var request = new TokenRequest { Email = email, MasterPasswordHash = hashedPassword, Device = deviceRequest, Remember = false }; if (twoFactorToken != null && twoFactorProvider != null) { request.Provider = twoFactorProvider; request.Token = twoFactorToken; request.Remember = remember.GetValueOrDefault(); } else if (storedTwoFactorToken != null) { request.Provider = TwoFactorProviderType.Remember; request.Token = storedTwoFactorToken; } var response = await _apiService.PostIdentityTokenAsync(request); ClearState(); var result = new AuthResult { TwoFactor = response.Item2 != null }; if (result.TwoFactor) { // Two factor required. var twoFactorResponse = response.Item2; Email = email; MasterPasswordHash = hashedPassword; _key = _setCryptoKeys ? key : null; TwoFactorProvidersData = twoFactorResponse.TwoFactorProviders2; result.TwoFactorProviders = twoFactorResponse.TwoFactorProviders2; return(result); } var tokenResponse = response.Item1; if (tokenResponse.TwoFactorToken != null) { await _tokenService.SetTwoFactorTokenAsync(tokenResponse.TwoFactorToken, email); } #region cozy _tokenService.SetClientInfos(tokenResponse.ClientId, tokenResponse.RegistrationAccessToken); #endregion await _tokenService.SetTokensAsync(tokenResponse.AccessToken, tokenResponse.RefreshToken); await _userService.SetInformationAsync(_tokenService.GetUserId(), _tokenService.GetEmail(), _kdf.Value, _kdfIterations.Value); if (_setCryptoKeys) { await _cryptoService.SetKeyAsync(key); await _cryptoService.SetKeyHashAsync(hashedPassword); await _cryptoService.SetEncKeyAsync(tokenResponse.Key); // User doesn't have a key pair yet (old account), let's generate one for them. if (tokenResponse.PrivateKey == null) { try { var keyPair = await _cryptoService.MakeKeyPairAsync(); await _apiService.PostAccountKeysAsync(new KeysRequest { PublicKey = keyPair.Item1, EncryptedPrivateKey = keyPair.Item2.EncryptedString }); tokenResponse.PrivateKey = keyPair.Item2.EncryptedString; } catch { } } await _cryptoService.SetEncPrivateKeyAsync(tokenResponse.PrivateKey); } _lockService.FingerprintLocked = false; _messagingService.Send("loggedIn"); return(result); }
public async Task <Models.LoginResult> TokenPostTwoFactorAsync(TwoFactorProviderType type, string token, bool remember, string email, string masterPasswordHash, SymmetricCryptoKey key) { var result = new Models.LoginResult(); var request = new TokenRequest { Remember = remember, Email = email.Trim().ToLower(), MasterPasswordHash = masterPasswordHash, Token = token, Provider = type, Device = new DeviceRequest(_appIdService, _deviceInfoService) }; var response = await _connectApiRepository.PostTokenAsync(request); if (!response.Succeeded) { result.Success = false; result.ErrorMessage = response.Errors.FirstOrDefault()?.Message; return(result); } result.Success = true; await ProcessLoginSuccessAsync(key, response.Result); return(result); }
public async Task <(Send send, CipherString encryptedFileData)> EncryptAsync(SendView model, byte[] fileData, string password, SymmetricCryptoKey key = null) { if (model.Key == null) { model.Key = _cryptoFunctionService.RandomBytes(16); model.CryptoKey = await _cryptoService.MakeSendKeyAsync(model.Key); } var send = new Send { Id = model.Id, Type = model.Type, Disabled = model.Disabled, MaxAccessCount = model.MaxAccessCount, Key = await _cryptoService.EncryptAsync(model.Key, key), Name = await _cryptoService.EncryptAsync(model.Name, model.CryptoKey), Notes = await _cryptoService.EncryptAsync(model.Notes, model.CryptoKey), }; CipherString encryptedFileData = null; if (password != null) { var passwordHash = await _cryptoFunctionService.Pbkdf2Async(password, model.Key, CryptoHashAlgorithm.Sha256, 100000); send.Password = Convert.ToBase64String(passwordHash); } switch (send.Type) { case SendType.Text: send.Text = new SendText { Text = await _cryptoService.EncryptAsync(model.Text.Text, model.CryptoKey), Hidden = model.Text.Hidden }; break; case SendType.File: send.File = new SendFile(); if (fileData != null) { send.File.FileName = await _cryptoService.EncryptAsync(model.File.FileName, model.CryptoKey); encryptedFileData = await _cryptoService.EncryptAsync(fileData, model.CryptoKey); } break; default: break; } return(send, encryptedFileData); }