mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
hmac check on rsa decrypt
This commit is contained in:
parent
1e5883f028
commit
7823ec3fc8
4 changed files with 43 additions and 10 deletions
|
@ -6,6 +6,8 @@
|
||||||
AesCbc128_HmacSha256_B64 = 1,
|
AesCbc128_HmacSha256_B64 = 1,
|
||||||
AesCbc256_HmacSha256_B64 = 2,
|
AesCbc256_HmacSha256_B64 = 2,
|
||||||
Rsa2048_OaepSha256_B64 = 3,
|
Rsa2048_OaepSha256_B64 = 3,
|
||||||
Rsa2048_OaepSha1_B64 = 4
|
Rsa2048_OaepSha1_B64 = 4,
|
||||||
|
Rsa2048_OaepSha256_HmacSha256_B64 = 5,
|
||||||
|
Rsa2048_OaepSha1_HmacSha256_B64 = 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,15 @@ namespace Bit.App.Models
|
||||||
}
|
}
|
||||||
CipherText = encPieces[0];
|
CipherText = encPieces[0];
|
||||||
break;
|
break;
|
||||||
|
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
|
||||||
|
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
|
||||||
|
if(encPieces.Length != 2)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Malformed encPieces.");
|
||||||
|
}
|
||||||
|
CipherText = encPieces[0];
|
||||||
|
Mac = encPieces[1];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unknown encType.");
|
throw new ArgumentException("Unknown encType.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,13 +323,24 @@ namespace Bit.App.Services
|
||||||
throw new ArgumentNullException(nameof(privateKey));
|
throw new ArgumentNullException(nameof(privateKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(EncKey?.MacKey != null && !string.IsNullOrWhiteSpace(encyptedValue.Mac))
|
||||||
|
{
|
||||||
|
var computedMacBytes = Crypto.ComputeMac(encyptedValue.CipherTextBytes, EncKey.MacKey);
|
||||||
|
if(!Crypto.MacsEqual(EncKey.MacKey, computedMacBytes, encyptedValue.MacBytes))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("MAC failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IAsymmetricKeyAlgorithmProvider provider = null;
|
IAsymmetricKeyAlgorithmProvider provider = null;
|
||||||
switch(encyptedValue.EncryptionType)
|
switch(encyptedValue.EncryptionType)
|
||||||
{
|
{
|
||||||
case EncryptionType.Rsa2048_OaepSha256_B64:
|
case EncryptionType.Rsa2048_OaepSha256_B64:
|
||||||
|
case EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
|
||||||
provider = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha256);
|
provider = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha256);
|
||||||
break;
|
break;
|
||||||
case EncryptionType.Rsa2048_OaepSha1_B64:
|
case EncryptionType.Rsa2048_OaepSha1_B64:
|
||||||
|
case EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
|
||||||
provider = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha1);
|
provider = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
using PCLCrypto;
|
using PCLCrypto;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Bit.App.Utilities
|
namespace Bit.App.Utilities
|
||||||
|
@ -63,19 +64,14 @@ namespace Bit.App.Utilities
|
||||||
return WinRTCrypto.CryptographicBuffer.GenerateRandom(length);
|
return WinRTCrypto.CryptographicBuffer.GenerateRandom(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ComputeMacBase64(byte[] ctBytes, byte[] ivBytes, byte[] macKey)
|
public static string ComputeMacBase64(byte[] ctBytes, byte[] ivBytes, byte[] macKey)
|
||||||
{
|
{
|
||||||
var mac = ComputeMac(ctBytes, ivBytes, macKey);
|
var mac = ComputeMac(ctBytes, ivBytes, macKey);
|
||||||
return Convert.ToBase64String(mac);
|
return Convert.ToBase64String(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] ComputeMac(byte[] ctBytes, byte[] ivBytes, byte[] macKey)
|
public static byte[] ComputeMac(byte[] ctBytes, byte[] ivBytes, byte[] macKey)
|
||||||
{
|
{
|
||||||
if(macKey == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(macKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ctBytes == null)
|
if(ctBytes == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(ctBytes));
|
throw new ArgumentNullException(nameof(ctBytes));
|
||||||
|
@ -86,16 +82,31 @@ namespace Bit.App.Utilities
|
||||||
throw new ArgumentNullException(nameof(ivBytes));
|
throw new ArgumentNullException(nameof(ivBytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ComputeMac(ivBytes.Concat(ctBytes), macKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] ComputeMac(IEnumerable<byte> dataBytes, byte[] macKey)
|
||||||
|
{
|
||||||
|
if(macKey == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(macKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dataBytes == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(dataBytes));
|
||||||
|
}
|
||||||
|
|
||||||
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
|
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
|
||||||
var hasher = algorithm.CreateHash(macKey);
|
var hasher = algorithm.CreateHash(macKey);
|
||||||
hasher.Append(ivBytes.Concat(ctBytes).ToArray());
|
hasher.Append(dataBytes.ToArray());
|
||||||
var mac = hasher.GetValueAndReset();
|
var mac = hasher.GetValueAndReset();
|
||||||
return mac;
|
return mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safely compare two MACs in a way that protects against timing attacks (Double HMAC Verification).
|
// Safely compare two MACs in a way that protects against timing attacks (Double HMAC Verification).
|
||||||
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
|
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
|
||||||
private static bool MacsEqual(byte[] macKey, byte[] mac1, byte[] mac2)
|
public static bool MacsEqual(byte[] macKey, byte[] mac1, byte[] mac2)
|
||||||
{
|
{
|
||||||
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
|
var algorithm = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha256);
|
||||||
var hasher = algorithm.CreateHash(macKey);
|
var hasher = algorithm.CreateHash(macKey);
|
||||||
|
|
Loading…
Reference in a new issue