/// <summary> /// Mask Generation Function /// </summary> /// <param name="Z">Initial pseudorandom Seed.</param> /// <param name="l">Length of output required.</param> /// <returns></returns> private byte[] MGF(byte[] Z, int l) { if (l > (Math.Pow(2, 32))) { throw new ArgumentException("Mask too long."); } else { List <byte> result = new List <byte>(); for (int i = 0; i <= l / rsaParams.hLen; i++) { List <byte> data = new List <byte>(); data.AddRange(Z); data.AddRange(RSAProviderUtils.I2OSP(i, 4, false)); result.AddRange(rsaParams.ComputeHash(data.ToArray())); } if (l <= result.Count) { return(result.GetRange(0, l).ToArray()); } else { throw new ArgumentException("Invalid Mask Length."); } } }
/// <summary> /// Low level RSA Process function for use with private key. /// Should never be used; Because without padding RSA is vulnerable to attacks. Use with caution. /// </summary> /// <param name="PlainText">Data to encrypt. Length must be less than Modulus size in octets.</param> /// <param name="usePrivate">True to use Private key, else Public.</param> /// <returns>Encrypted Data</returns> public byte[] RSAProcess(byte[] PlainText, bool usePrivate) { if (usePrivate && !rsaParams.Has_PRIVATE_Info) { throw new CryptographicException("RSA Process: Incomplete Private Key Info"); } if ((usePrivate == false) && !rsaParams.Has_PUBLIC_Info) { throw new CryptographicException("RSA Process: Incomplete Public Key Info"); } BigInteger _E; if (usePrivate) { _E = rsaParams.D; } else { _E = rsaParams.E; } var PT = RSAProviderUtils.OS2IP(PlainText, false); var M = BigInteger.ModPow(PT, _E, rsaParams.N); if (M.Sign == -1) { return(RSAProviderUtils.I2OSP(M + rsaParams.N, rsaParams.OctetsInModulus, false)); } return(RSAProviderUtils.I2OSP(M, rsaParams.OctetsInModulus, false)); }
/// <summary> /// Low level RSA Decryption function for use with private key. Uses CRT and is Much faster. /// Should never be used; Because without padding RSA is vulnerable to attacks. Use with caution. /// </summary> /// <param name="Data">Data to encrypt. Length must be less than Modulus size in octets.</param> /// <returns>Encrypted Data</returns> public byte[] RSADecryptPrivateCRT(byte[] Data) { if (rsaParams.Has_PRIVATE_Info && rsaParams.HasCRTInfo) { BigInteger C = RSAProviderUtils.OS2IP(Data, false); BigInteger M1 = BigInteger.ModPow(C, rsaParams.DP, rsaParams.P); BigInteger M2 = BigInteger.ModPow(C, rsaParams.DQ, rsaParams.Q); BigInteger H = ((M1 - M2) * rsaParams.InverseQ) % rsaParams.P; BigInteger M = (M2 + (rsaParams.Q * H)); if (M.Sign == -1) { return(RSAProviderUtils.I2OSP(M + rsaParams.N, rsaParams.OctetsInModulus, false)); } else { return(RSAProviderUtils.I2OSP(M, rsaParams.OctetsInModulus, false)); } } else { throw new CryptographicException("RSA Decrypt CRT: Incomplete Key Info"); } }