📄 rsacryptoserviceprovider.cs
字号:
if(padding.Length <= padlen) { Array.Copy(padding, 0, msg, posn, padding.Length); } else { Array.Copy(padding, 0, msg, posn, padlen); } } posn += padlen; msg[posn++] = (byte)0x01; Array.Copy(rgb, 0, msg, posn, rgb.Length); // Acquire a mask generation method, based on SHA-1. MaskGenerationMethod maskGen = new PKCS1MaskGenerationMethod(); // Generate a random seed to use to generate masks. byte[] seed = new byte [20]; rng.GetBytes(seed); // Generate a mask and encrypt the above message. byte[] mask = maskGen.GenerateMask(seed, msg.Length); int index; for(index = 0; index < msg.Length; ++index) { msg[index] ^= mask[index]; } // Generate another mask and encrypt the seed. byte[] seedMask = maskGen.GenerateMask(msg, 20); for(index = 0; index < 20; ++index) { seed[index] ^= seedMask[index]; } // Build the value to be encrypted using RSA. byte[] value = new byte [k]; Array.Copy(seed, 0, value, 1, 20); Array.Copy(msg, 0, value, 21, msg.Length); // Encrypt the value. byte[] encrypted = ApplyPublic(value); // Destroy sensitive data. Array.Clear(msg, 0, msg.Length); Array.Clear(seed, 0, seed.Length); Array.Clear(mask, 0, mask.Length); Array.Clear(seedMask, 0, seedMask.Length); Array.Clear(value, 0, value.Length); // Done. return encrypted; } // Encrypt a value using the RSA public key and the PKCS1 encoding. internal byte[] EncryptPKCS1(byte[] rgb, RandomNumberGenerator rng) { // Check the data against null. if(rgb == null) { throw new ArgumentNullException("rgb"); } // Make sure that we have sufficient RSA parameters. if(rsaParams.Modulus == null) { throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } // Format the type codes, padding string, and data. int k = rsaParams.Modulus.Length; if(rgb.Length > (k - 11)) { throw new CryptographicException (_("Crypto_RSAMessageTooLong")); } byte[] msg = new byte [k]; msg[1] = (byte)0x02; byte[] padding = new byte [k - rgb.Length - 3]; rng.GetNonZeroBytes(padding); Array.Copy(padding, 0, msg, 2, padding.Length); Array.Copy(rgb, 0, msg, k - rgb.Length, rgb.Length); // Encrypt the message. byte[] encrypted = ApplyPublic(msg); // Destroy sensitive data. Array.Clear(msg, 0, msg.Length); Array.Clear(padding, 0, padding.Length); // Done. return encrypted; } // Encrypt a value using the RSA private key and optional OAEP padding. public byte[] Encrypt(byte[] rgb, bool fOAEP) { if(fOAEP) { return EncryptOAEP (rgb, null, new RNGCryptoServiceProvider()); } else { return EncryptPKCS1(rgb, new RNGCryptoServiceProvider()); } } // Encrypt a value using the RSA public key. public override byte[] EncryptValue(byte[] rgb) { return EncryptPKCS1(rgb, new RNGCryptoServiceProvider()); } // Export the parameters for RSA signature generation. public override RSAParameters ExportParameters (bool includePrivateParameters) { if(rsaParams.Modulus == null) { throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } if(includePrivateParameters) { return rsaParams; } else { return rsaParams.ClonePublic(); } } // Import the parameters for DSA signature generation. public override void ImportParameters(RSAParameters parameters) { // We need at least Modulus and Exponent for public key ops. if(parameters.Modulus == null || parameters.Exponent == null || CryptoMethods.NumZero(parameters.Modulus) || CryptoMethods.NumZero(parameters.Exponent)) { throw new CryptographicException (_("Crypto_InvalidRSAParams")); } rsaParams = parameters; } // Convert a "halg" value into a HashAlgorithm instance. private static HashAlgorithm ObjectToHashAlg(Object halg) { HashAlgorithm alg; if(halg == null) { throw new ArgumentNullException("halg"); } else if(halg is String) { alg = HashAlgorithm.Create((String)halg); } else if(halg is HashAlgorithm) { alg = (HashAlgorithm)halg; } else if(halg is Type && ((Type)halg).IsSubclassOf(typeof(HashAlgorithm))) { alg = (HashAlgorithm)(Activator.CreateInstance((Type)halg)); } else { throw new ArgumentException (_("Crypto_NeedsHash"), "halg"); } if(!(alg is SHA1) && !(alg is MD5) && !(alg is SHA256) && !(alg is SHA384) && !(alg is SHA512)) { throw new CryptographicException (_("Crypto_PKCS1Hash")); } return alg; } // PKCS #1 headers for various hash algorithms. private static readonly byte[] md5Header = {(byte)0x30, (byte)0x20, (byte)0x30, (byte)0x0C, (byte)0x06, (byte)0x08, (byte)0x2A, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xF7, (byte)0x0D, (byte)0x02, (byte)0x05, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x10}; private static readonly byte[] sha1Header = {(byte)0x30, (byte)0x21, (byte)0x30, (byte)0x09, (byte)0x06, (byte)0x05, (byte)0x2B, (byte)0x0E, (byte)0x03, (byte)0x02, (byte)0x1A, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x14}; private static readonly byte[] sha256Header = {(byte)0x30, (byte)0x31, (byte)0x30, (byte)0x0D, (byte)0x06, (byte)0x09, (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, (byte)0x03, (byte)0x04, (byte)0x02, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x20}; private static readonly byte[] sha384Header = {(byte)0x30, (byte)0x41, (byte)0x30, (byte)0x0D, (byte)0x06, (byte)0x09, (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, (byte)0x03, (byte)0x04, (byte)0x02, (byte)0x02, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x30}; private static readonly byte[] sha512Header = {(byte)0x30, (byte)0x41, (byte)0x30, (byte)0x0D, (byte)0x06, (byte)0x09, (byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65, (byte)0x03, (byte)0x04, (byte)0x02, (byte)0x03, (byte)0x05, (byte)0x00, (byte)0x04, (byte)0x40}; // Convert a hash algorithm instance into a PKCS #1 header. private byte[] HashAlgToHeader(HashAlgorithm alg) { if(alg is MD5) { return md5Header; } else if(alg is SHA1) { return sha1Header; } else if(alg is SHA256) { return sha256Header; } else if(alg is SHA384) { return sha384Header; } else { return sha512Header; } } // Convert a hash algorithm name into a PKCS #1 header. private byte[] HashAlgToHeader(String alg) { if(alg == "MD5") { return md5Header; } else if(alg == null || alg == "SHA1") { return sha1Header; } else if(alg == "SHA256") { return sha256Header; } else if(alg == "SHA384") { return sha384Header; } else if(alg == "SHA512") { return sha512Header; } else { throw new CryptographicException (_("Crypto_PKCS1Hash")); } } // Perform a sign operation. private byte[] Sign(byte[] rgbHash, byte[] header) { // Validate the parameters. if(rgbHash == null) { throw new ArgumentNullException("rgbHash"); } if(rgbHash.Length != header[header.Length - 1]) { throw new CryptographicException (_("Crypto_InvalidHashSize")); } // Make sure that we have sufficient RSA parameters. if(rsaParams.Modulus == null) { throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } // Check the length of the incoming value. int k = rsaParams.Modulus.Length; if(k < (header.Length + rgbHash.Length + 11)) { throw new CryptographicException (_("Crypto_RSAKeyTooShort")); } // Format the value to be signed. byte[] msg = new byte [k]; msg[1] = (byte)0x01; int index, posn; posn = k - header.Length - rgbHash.Length; for(index = 2; index < (posn - 1); ++index) { msg[posn] = (byte)0xFF; } Array.Copy(header, 0, msg, posn, header.Length); Array.Copy(rgbHash, 0, msg, posn + header.Length, rgbHash.Length); // Sign the value with the private key. byte[] signedValue = ApplyPrivate(msg); if(signedValue.Length < k) { // Zero-extend the value if necessary. byte[] zextend = new byte [k]; Array.Copy(signedValue, 0, zextend, k - signedValue.Length, signedValue.Length); Array.Clear(signedValue, 0, signedValue.Length); signedValue = zextend; } // Destroy sensitive values. Array.Clear(msg, 0, msg.Length); // Done. return signedValue; } // Compute a hash value over a buffer and sign it. public byte[] SignData(byte[] buffer, Object halg) { HashAlgorithm alg = ObjectToHashAlg(halg); return Sign(alg.ComputeHash(buffer), HashAlgToHeader(alg)); } // Compute a hash value over a buffer fragment and sign it. public byte[] SignData(byte[] buffer, int offset, int count, Object halg) { HashAlgorithm alg = ObjectToHashAlg(halg); return Sign(alg.ComputeHash(buffer, offset, count), HashAlgToHeader(alg)); } // Compute a hash value over a stream and sign it. public byte[] SignData(Stream inputStream, Object halg) { HashAlgorithm alg = ObjectToHashAlg(halg); return Sign(alg.ComputeHash(inputStream), HashAlgToHeader(alg)); } // Sign an explicit hash value. public byte[] SignHash(byte[] rgbHash, String str) { return Sign(rgbHash, HashAlgToHeader(str)); } // Perform a verify operation. private bool Verify(byte[] rgbHash, byte[] header, byte[] rgbSignature) { // Validate the parameters. if(rgbHash == null) { throw new ArgumentNullException("rgbHash"); } if(rgbHash.Length != header[header.Length - 1]) { throw new CryptographicException (_("Crypto_InvalidHashSize")); } if(rgbSignature == null) { throw new ArgumentNullException("rgbSignature"); } // Make sure that we have sufficient RSA parameters. if(rsaParams.Modulus == null) { throw new CryptographicException (_("Crypto_RSAParamsNotSet")); } // Check the length of the incoming value. int k = rsaParams.Modulus.Length; if(k < (header.Length + rgbHash.Length + 11)) { throw new CryptographicException (_("Crypto_RSAKeyTooShort")); } // Decode the signed value. byte[] msg = ApplyPublic(rgbSignature); if(msg.Length < k) { // Zero-extend the value if necessary. byte[] zextend = new byte [k]; Array.Copy(msg, 0, zextend, k - msg.Length, msg.Length); Array.Clear(msg, 0, msg.Length); msg = zextend; } // Check the decoded value against the expected data. bool ok = (msg[0] == 0x00 && msg[1] == 0x01); int index, posn; posn = k - header.Length - rgbHash.Length; for(index = 2; index < (posn - 1); ++index) { if(msg[posn] != 0xFF) { ok = false; } } if(msg[posn - 1] != 0x00) { ok = false; } for(index = 0; index < rgbHash.Length; ++index) { if(msg[posn + index] != rgbHash[index]) { ok = false; } } // Destroy sensitive values. Array.Clear(msg, 0, msg.Length); // Done. return ok; } // Verify the signature on a buffer of data. public bool VerifyData(byte[] buffer, Object halg, byte[] rgbSignature) { HashAlgorithm alg = ObjectToHashAlg(halg); return Verify(alg.ComputeHash(buffer), HashAlgToHeader(alg), rgbSignature); } // Verify a signature from an explicit hash value. public bool VerifyHash(byte[] rgbHash, String str, byte[] rgbSignature) { return Verify(rgbHash, HashAlgToHeader(str), rgbSignature); }}; // class RSACryptoServiceProvider#endif // CONFIG_CRYPTO}; // namespace System.Security.Cryptography
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -