Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(iot-svc): Cleanup and deprecation warning of code in CryptoKeyGenerator #2187

Merged
merged 5 commits into from
Oct 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions e2e/test/helpers/CryptoKeyGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Security.Cryptography;

#if !NET451

using System.Linq;

#endif

namespace Microsoft.Azure.Devices.E2ETests
{
/// <summary>
/// Utility methods for generating cryptographically secure keys and passwords.
/// </summary>
internal static class CryptoKeyGenerator
{
#if NET451
private const int DefaultPasswordLength = 16;
private const int GuidLength = 16;
#endif

/// <summary>
/// Size of the SHA 512 key.
/// </summary>
internal const int Sha512KeySize = 64;

/// <summary>
/// Generate a key with a specified key size.
/// </summary>
/// <param name="keySize">The size of the key.</param>
/// <returns>Byte array representing the key.</returns>
internal static byte[] GenerateKeyBytes(int keySize)
{
#if NET451
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = new RNGCryptoServiceProvider();
cyptoProvider.GetNonZeroBytes(keyBytes);
#else
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = RandomNumberGenerator.Create();
while (keyBytes.Contains(byte.MinValue))
{
cyptoProvider.GetBytes(keyBytes);
}
#endif
return keyBytes;
}

/// <summary>
/// Generates a key of the specified size.
/// </summary>
/// <param name="keySize">Desired key size.</param>
/// <returns>A generated key.</returns>
internal static string GenerateKey(int keySize)
{
return Convert.ToBase64String(GenerateKeyBytes(keySize));
}
}
}
2 changes: 0 additions & 2 deletions e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Common;
using Microsoft.Azure.Devices.Provisioning.Security.Samples;
using Microsoft.Azure.Devices.Provisioning.Service;
using Microsoft.Azure.Devices.Shared;
Expand Down
86 changes: 49 additions & 37 deletions iothub/service/src/Common/Security/CryptoKeyGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Linq;
using System;
using System.Text;
using System.Security.Cryptography;

#if NET451

using System.Web.Security;

#endif

#if !NET451

using System.Security.Cryptography;
using System.Linq;

#else
using System.Web.Security;
using System.Security.Cryptography;
#endif

namespace Microsoft.Azure.Devices.Common
{
/// <summary>
/// Utility methods for generating cryptographically secure keys and passwords.
/// </summary>
static public class CryptoKeyGenerator
public static class CryptoKeyGenerator
{
#if NET451
const int DefaultPasswordLength = 16;
const int GuidLength = 16;
private const int DefaultPasswordLength = 16;
private const int GuidLength = 16;
#endif

/// <summary>
Expand All @@ -36,22 +39,19 @@ static public class CryptoKeyGenerator
/// </summary>
/// <param name="keySize">The size of the key.</param>
/// <returns>Byte array representing the key.</returns>
[Obsolete("This method will be deprecated in a future version.")]
public static byte[] GenerateKeyBytes(int keySize)
drwill-ms marked this conversation as resolved.
Show resolved Hide resolved
{
#if !NET451
drwill-ms marked this conversation as resolved.
Show resolved Hide resolved
var keyBytes = new byte[keySize];
using (var cyptoProvider = RandomNumberGenerator.Create())
{
while (keyBytes.Contains(byte.MinValue))
{
cyptoProvider.GetBytes(keyBytes);
}
}
#if NET451
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = new RNGCryptoServiceProvider();
cyptoProvider.GetNonZeroBytes(keyBytes);
#else
var keyBytes = new byte[keySize];
using (var cyptoProvider = new RNGCryptoServiceProvider())
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = RandomNumberGenerator.Create();
while (keyBytes.Contains(byte.MinValue))
{
cyptoProvider.GetNonZeroBytes(keyBytes);
cyptoProvider.GetBytes(keyBytes);
}
#endif
return keyBytes;
Expand All @@ -62,6 +62,7 @@ public static byte[] GenerateKeyBytes(int keySize)
/// </summary>
/// <param name="keySize">Desired key size.</param>
/// <returns>A generated key.</returns>
[Obsolete("This method will be deprecated in a future version.")]
public static string GenerateKey(int keySize)
{
return Convert.ToBase64String(GenerateKeyBytes(keySize));
Expand All @@ -72,44 +73,54 @@ public static string GenerateKey(int keySize)
/// Generate a hexadecimal key of the specified size.
/// </summary>
/// <param name="keySize">Desired key size.</param>
/// <returns>A generated hexadecimal key.</returns>
/// <returns>A generated hexadecimal key.</returns>
[Obsolete("This method will not be carried forward to newer .NET targets.")]
public static string GenerateKeyInHex(int keySize)
{
var keyBytes = new byte[keySize];
using (var cyptoProvider = new RNGCryptoServiceProvider())
{
cyptoProvider.GetNonZeroBytes(keyBytes);
}
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = new RNGCryptoServiceProvider();
cyptoProvider.GetNonZeroBytes(keyBytes);

return BitConverter.ToString(keyBytes).Replace("-", "");
}

/// <summary>
/// Generate a GUID using random bytes from the framework's cryptograpically strong RNG (Random Number Generator).
/// </summary>
/// <returns>A cryptographically secure GUID.</returns>
[Obsolete("This method will not be carried forward to newer .NET targets.")]
public static Guid GenerateGuid()
{
byte[] bytes = new byte[GuidLength];
using (var rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(bytes);
}
using var rng = new RNGCryptoServiceProvider();
rng.GetBytes(bytes);

var time = BitConverter.ToUInt32(bytes, 0);
var time_mid = BitConverter.ToUInt16(bytes, 4);
var time_hi_and_ver = BitConverter.ToUInt16(bytes, 6);
time_hi_and_ver = (ushort)((time_hi_and_ver | 0x4000) & 0x4FFF);
uint time = BitConverter.ToUInt32(bytes, 0);
ushort timeMid = BitConverter.ToUInt16(bytes, 4);
ushort timeHiAndVer = BitConverter.ToUInt16(bytes, 6);
timeHiAndVer = (ushort)((timeHiAndVer | 0x4000) & 0x4FFF);

bytes[8] = (byte)((bytes[8] | 0x80) & 0xBF);

return new Guid(time, time_mid, time_hi_and_ver, bytes[8], bytes[9],
bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);
return new Guid(
time,
timeMid,
timeHiAndVer,
bytes[8],
bytes[9],
bytes[10],
bytes[11],
bytes[12],
bytes[13],
bytes[14],
bytes[15]);
}

/// <summary>
/// Generate a unique password with a default length and without converting it to Base64String.
/// </summary>
/// <returns>A unique password.</returns>
[Obsolete("This method will not be carried forward to newer .NET targets.")]
public static string GeneratePassword()
{
return GeneratePassword(DefaultPasswordLength, false);
Expand All @@ -121,9 +132,10 @@ public static string GeneratePassword()
/// <param name="length">Desired length of the password.</param>
/// <param name="base64Encoding">Encode the password if set to True. False otherwise.</param>
/// <returns>A generated password.</returns>
[Obsolete("This method will not be carried forward to newer .NET targets.")]
public static string GeneratePassword(int length, bool base64Encoding)
{
var password = Membership.GeneratePassword(length, length / 2);
string password = Membership.GeneratePassword(length, length / 2);
if (base64Encoding)
{
password = Convert.ToBase64String(Encoding.UTF8.GetBytes(password));
Expand Down
62 changes: 62 additions & 0 deletions iothub/service/tests/CryptoKeyGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Security.Cryptography;

#if !NET451

using System.Linq;

#endif

namespace Microsoft.Azure.Devices.Tests
{
/// <summary>
/// Utility methods for generating cryptographically secure keys and passwords.
/// </summary>
internal static class CryptoKeyGenerator
{
#if NET451
private const int DefaultPasswordLength = 16;
private const int GuidLength = 16;
#endif

/// <summary>
/// Size of the SHA 512 key.
/// </summary>
internal const int Sha512KeySize = 64;

/// <summary>
/// Generate a key with a specified key size.
/// </summary>
/// <param name="keySize">The size of the key.</param>
/// <returns>Byte array representing the key.</returns>
internal static byte[] GenerateKeyBytes(int keySize)
{
#if NET451
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = new RNGCryptoServiceProvider();
cyptoProvider.GetNonZeroBytes(keyBytes);
#else
byte[] keyBytes = new byte[keySize];
using var cyptoProvider = RandomNumberGenerator.Create();
while (keyBytes.Contains(byte.MinValue))
{
cyptoProvider.GetBytes(keyBytes);
}
#endif
return keyBytes;
}

/// <summary>
/// Generates a key of the specified size.
/// </summary>
/// <param name="keySize">Desired key size.</param>
/// <returns>A generated key.</returns>
internal static string GenerateKey(int keySize)
{
return Convert.ToBase64String(GenerateKeyBytes(keySize));
}
}
}
2 changes: 1 addition & 1 deletion iothub/service/tests/DeviceAuthenticationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Common;
using Microsoft.Azure.Devices.Tests;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

Expand Down