Skip to content

Commit

Permalink
AES support and refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
CoolandonRS committed Jul 28, 2023
1 parent 6aaa2e1 commit b6877f1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 39 deletions.
61 changes: 61 additions & 0 deletions keyring/AESUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
using System.Text;

namespace CoolandonRS.keyring;

public class AESUtil : EncryptionUtil {
private Aes aes;
private byte[] ivKey;
private int interactionCount;
private object @lock;

Check warning on line 11 in keyring/AESUtil.cs

View workflow job for this annotation

GitHub Actions / build

Field 'AESUtil.@lock' is never assigned to, and will always have its default value null

Check warning on line 11 in keyring/AESUtil.cs

View workflow job for this annotation

GitHub Actions / build

Field 'AESUtil.@lock' is never assigned to, and will always have its default value null

public override byte[] Encrypt(byte[] b) {
lock (@lock) {
DeriveIV();
return aes.EncryptCbc(b, aes.IV);
}
}

public override byte[] Decrypt(byte[] b) {
lock (@lock) {
DeriveIV();
return aes.DecryptCbc(b, aes.IV);
}
}

public (byte[] key, byte[] ivKey) GetSecrets() {
lock (@lock) {
if (interactionCount != -1) throw new InvalidOperationException("This AESUtil has already been used. Secrets are not retrievable.");
return (aes.Key, ivKey);
}
}

private static Aes MakeAes(byte[] key) {
var aes = Aes.Create();
aes.KeySize = key.Length;
aes.Key = key;
return aes;
}

private void DeriveIV() {
interactionCount++;
aes.IV = Rfc2898DeriveBytes.Pbkdf2(ivKey, BitConverter.GetBytes(interactionCount), 15000, HashAlgorithmName.SHA256, 16);
}

private AESUtil(KeyType keyType, byte[] ivKey, Aes aes, Encoding? encoding = null) : base(keyType, encoding) {

Check warning on line 46 in keyring/AESUtil.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'lock' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 46 in keyring/AESUtil.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'lock' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
if (keyType != KeyType.Symmetric) throw new InvalidOperationException("AESUtil only supports symmetric keys");
this.aes = aes;
this.ivKey = ivKey;
this.interactionCount = -1;
}

/// <summary>
/// Generates a new AES key to use for the AESUtil
/// </summary>
public AESUtil(Encoding? encoding = null) : this(KeyType.Symmetric, RandomNumberGenerator.GetBytes(64), Aes.Create(), encoding) {
}

public AESUtil(KeyType keyType, byte[] key, byte[] ivKey, Encoding? encoding = null) : this(keyType, ivKey, MakeAes(key), encoding) {
}
}
35 changes: 35 additions & 0 deletions keyring/EncryptionUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Security.Cryptography;
using System.Text;

namespace CoolandonRS.keyring;

public abstract class EncryptionUtil {
protected readonly KeyType keyType;
protected readonly Encoding encoding;

/// <summary>
/// Encrypts data using the stored key(s)
/// </summary>
/// <param name="dat">Data to encrypt</param>
/// <returns>Encrypted data</returns>
public abstract byte[] Encrypt(byte[] b);

public virtual byte[] EncryptStr(string s) => Encrypt(encoding.GetBytes(s));

/// <summary>
/// Decrypts data using the stored key(s)
/// </summary>
/// <param name="dat">Data to decrypt</param>
/// <returns>Decrypted Data</returns>
/// <exception cref="InvalidOperationException">Unable to decrypt</exception>
public abstract byte[] Decrypt(byte[] b);

public virtual string DecryptStr(byte[] b) => encoding.GetString(Decrypt(b));

public KeyType GetKeyType() => keyType;

protected EncryptionUtil(KeyType type, Encoding? encoding) {
this.keyType = type;
this.encoding = encoding ?? Encoding.UTF8;
}
}
47 changes: 8 additions & 39 deletions keyring/RSAUtil.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,38 @@
using System.Security.Cryptography;
using System.CodeDom.Compiler;
using System.Security.Cryptography;
using System.Text;

namespace CoolandonRS.keyring;

/// <summary>
/// Tool for using RSA Encryption/Decryption
/// </summary>
public class RSAUtil {
public class RSAUtil : EncryptionUtil {
private RSACryptoServiceProvider provider;
private readonly KeyType keyType;
private Encoding encoding;

Check warning on line 12 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

'RSAUtil.encoding' hides inherited member 'EncryptionUtil.encoding'. Use the new keyword if hiding was intended.

Check warning on line 12 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

The field 'RSAUtil.encoding' is never used

Check warning on line 12 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

'RSAUtil.encoding' hides inherited member 'EncryptionUtil.encoding'. Use the new keyword if hiding was intended.

Check warning on line 12 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

The field 'RSAUtil.encoding' is never used

/// <summary>
/// Encrypts data using the stored key(s)
/// </summary>
/// <param name="dat">Data to encrypt</param>
/// <returns>Encrypted data</returns>
public byte[] Encrypt(byte[] dat) {

public override byte[] Encrypt(byte[] dat) {
return provider.Encrypt(dat, false);
}

/// <summary>
/// Encodes and encrypts a string using the chosen encoding and stored key(s)
/// </summary>
/// <param name="str">String to encode and encrypt</param>
/// <returns>Encrypted data</returns>
public byte[] EncryptStr(string str) {
return Encrypt(encoding.GetBytes(str));
}

/// <summary>
/// Decrypts data using the stored key(s)
/// </summary>
/// <param name="dat">Data to decrypt</param>
/// <returns>Decrypted Data</returns>
/// <exception cref="InvalidOperationException"></exception>
public byte[] Decrypt(byte[] dat) {

public override byte[] Decrypt(byte[] dat) {
if (keyType != KeyType.Private) throw new InvalidOperationException("Cannot decrypt if keyType is not private");
return provider.Decrypt(dat, false);
}

/// <summary>
/// Decrypts data and encodes it into a string using the chosen encoding and stored key(s)
/// </summary>
/// <param name="dat">Encrypted data</param>
/// <returns>Decrypted string</returns>
public string DecryptStr(byte[] dat) {
return encoding.GetString(Decrypt(dat));
}

/// <summary>
/// Creates an instance of RSAUtil
/// </summary>
/// <param name="keyType">The type of key you are providing</param>
/// <param name="pemContents">The contents of the PEM file</param>
/// <param name="encoding">The text encoding to use for strings</param>
/// <exception cref="InvalidOperationException">If you provide a symmetric key</exception>
public RSAUtil(KeyType keyType, string pemContents, Encoding? encoding = null) {
public RSAUtil(KeyType keyType, string pemContents, Encoding? encoding = null) : base(keyType, encoding) {

Check warning on line 30 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'encoding' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 30 in keyring/RSAUtil.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'encoding' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
if (keyType == KeyType.Symmetric) throw new InvalidOperationException("RSAUtil does not support symmetric keys");
// ReSharper disable once LocalVariableHidesMember // Intentional
var provider = new RSACryptoServiceProvider();
provider.ImportFromPem(pemContents);
if (keyType == KeyType.Private && provider.PublicOnly) throw new ArgumentException("keyType reported as private; no private key found.");
this.keyType = keyType;
this.provider = provider;
this.encoding = encoding ?? Encoding.UTF8;
}
}

0 comments on commit b6877f1

Please sign in to comment.