/// <summary> /// Initializes a new instance of the <see cref="ASymmetricEncryption"/> class. /// </summary> /// <param name="key"> /// The private key that will be used to decrypt the password used to decrypt the password. /// </param> /// <param name="password">The password to use during the symmetric part of the encryption.</param> /// <exception cref="ArgumentNullException"> /// password - A password must be provided! or key - An RSA public key must be provided. /// </exception> public ASymmetricEncryption(RsaPublicKey key, EncryptionData password) { password = Check.NotNull(password, nameof(password)); if (password.IsEmpty) { throw new ArgumentNullException(nameof(password), "A password must be provided!"); } if (password.Text.Length > 32) { throw new ArgumentOutOfRangeException( nameof(password), "RSA Encryption limits the password to 32 characters"); } _publicKey = key ?? throw new ArgumentNullException( nameof(key), "An RSA private key must be provided!"); _password = Equals(password.EncodingToUse, Encoding.UTF8) ? password : new EncryptionData(password.Text, Encoding.UTF8); EncryptedPassword = new RsaEncryption().Encrypt(_password, _publicKey); }
/// <summary> /// Load public key from the application or web configuration file. /// </summary> /// <returns>an RSA Public Key instance containing the public key, or null.</returns> public static RsaPublicKey LoadFromEnvironment() { var key = new RsaPublicKey { Modulus = ReadKeyFromEnvironment(_keyModulus), Exponent = ReadKeyFromEnvironment(_keyExponent) }; return(key); }
/// <summary> /// Creates a public key based on this private key. /// </summary> /// <returns>a public key based on this private key.</returns> public RsaPublicKey ToPublicKey() { var publicKey = new RsaPublicKey { Exponent = Exponent, Modulus = Modulus }; return(publicKey); }
/// <summary> /// Encrypts data using the provided public key. /// </summary> /// <param name="data">The data to be encrypted..</param> /// <param name="publicKey">The public key.</param> /// <returns>The encrypted data.</returns> public EncryptionData Encrypt(EncryptionData data, RsaPublicKey publicKey) { var rsa = GetRsaProvider(); rsa.ImportParameters(Check.NotNull(publicKey, nameof(publicKey)).ToParameters()); try { var encryptedBytes = rsa.Encrypt(Check.NotNull(data, nameof(data)).Bytes, true); // Be aware the RSACryptoServiceProvider reverses the order of encrypted bytes after // encryption and before decryption. In order to provide compatibility with other // providers, we reverse the order of the bytes to match what other providers output. Array.Reverse(encryptedBytes); return(new EncryptionData(encryptedBytes)); } catch (CryptographicException ex) { _log.Error(ex.Message, ex); var sb = new StringBuilder(); sb.Append("Your data is too large; RSA implementation in .Net is designed to encrypt "); sb.Append("relatively small amounts of data. The exact byte limit depends "); sb.Append("on the key size. To encrypt more data, use symmetric encryption "); sb.Append("and then encrypt that symmetric key with "); sb.Append("asymmetric encryption."); _log.Warn(sb.ToString()); throw new CryptographicException(sb.ToString(), ex); } catch (Exception ex) { _log.Error(ex.ToString(), ex); throw; } finally { rsa.Clear(); rsa.Dispose(); } }
/// <summary> /// Verifies that the provided data has not changed since it was signed. /// </summary> /// <param name="data">The data to be validated.</param> /// <param name="signature">The signature to use to verify data.</param> /// <param name="publicKey">The public key.</param> /// <returns> /// <c>true</c> if the provided data has not changed since it was signed, otherwise <c>false</c>. /// </returns> public bool Verify(EncryptionData data, EncryptionData signature, RsaPublicKey publicKey) { var rsa = GetRsaProvider(); rsa.ImportParameters(Check.NotNull(publicKey, nameof(publicKey)).ToParameters()); var hash = new SHA256Managed(); var valid = rsa.VerifyData( Check.NotNull(data, nameof(data)).Bytes, hash, Check.NotNull(signature, nameof(signature)).Bytes); rsa.Clear(); rsa.Dispose(); hash.Dispose(); return(valid); }
/// <summary> /// Initializes a new instance of the <see cref="ASymmetricEncryption"/> class. /// </summary> /// <param name="key"> /// The private key that will be used to decrypt the password used to decrypt the password. /// </param> /// <exception cref="ArgumentNullException">An RSA public key must be provided.</exception> public ASymmetricEncryption(RsaPublicKey key) { _publicKey = key ?? throw new ArgumentNullException( nameof(key), "An RSA public key must be provided!"); var random = CryptoRandomNumber.Next(); var generator = new PasswordGenerator(random) { IncludeExtended = false }; _password = new EncryptionData(generator.Generate(32)); EncryptedPassword = new RsaEncryption().Encrypt(_password, _publicKey); }
/// <summary> /// Generates a new public/private key pair as objects. /// </summary> /// <param name="publicKey">The public key.</param> /// <param name="privateKey">The private key.</param> public void GenerateNewKeyset(ref RsaPublicKey publicKey, ref RsaPrivateKey privateKey) { if (publicKey == null) { throw new ArgumentNullException(nameof(publicKey)); } if (privateKey == null) { throw new ArgumentNullException(nameof(privateKey)); } var rsa = GetRsaProvider(); var publicKeyXml = rsa.ToXmlString(false); var privateKeyXml = rsa.ToXmlString(true); rsa.Clear(); rsa.Dispose(); publicKey = new RsaPublicKey(publicKeyXml); privateKey = new RsaPrivateKey(privateKeyXml); }