internal ImmutableArray <byte> GetHash(AssemblyHashAlgorithm algorithmId) { using (HashAlgorithm? algorithm = TryGetAlgorithm(algorithmId)) { // ERR_CryptoHashFailed has already been reported: if (algorithm == null) { return(ImmutableArray.Create <byte>()); } switch (algorithmId) { case AssemblyHashAlgorithm.None: case AssemblyHashAlgorithm.Sha1: return(GetHash(ref _lazySHA1Hash, algorithm)); case AssemblyHashAlgorithm.Sha256: return(GetHash(ref _lazySHA256Hash, algorithm)); case AssemblyHashAlgorithm.Sha384: return(GetHash(ref _lazySHA384Hash, algorithm)); case AssemblyHashAlgorithm.Sha512: return(GetHash(ref _lazySHA512Hash, algorithm)); case AssemblyHashAlgorithm.MD5: return(GetHash(ref _lazyMD5Hash, algorithm)); default: throw ExceptionUtilities.UnexpectedValue(algorithmId); } } }
/// <summary> /// Constructor for the Checksum class used for computing file checksum. /// </summary> /// <param name="algorithm">Algorithm to be used for hashing.</param> /// <remarks> /// Supported hash algorithms: { MD5, SHA1, SHA256 }. /// If <see langword="Algorithm.None" />, do not compute any file hash. /// Default hash algorithm is MD5, if input algorithm is unsupported or null. /// </remarks> public Checksum(Algorithm algorithm) { switch (algorithm) { case Algorithm.None: _hashAlgorithm = null; AlgorithmName = new HashAlgorithmName("None"); break; case Algorithm.SHA1: _hashAlgorithm = SHA1.Create(); AlgorithmName = HashAlgorithmName.SHA1; break; case Algorithm.SHA256: _hashAlgorithm = SHA256.Create(); AlgorithmName = HashAlgorithmName.SHA256; break; case Algorithm.MD5: default: _hashAlgorithm = MD5.Create(); AlgorithmName = HashAlgorithmName.MD5; break; } ; }
public override byte[] GenerateMask(byte[] rgbSeed, int cbReturn) { using (HashAlgorithm? hasher = CryptoConfig.CreateFromName(_hashNameValue) as HashAlgorithm) { if (hasher is null) { throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, _hashNameValue)); } byte[] rgbCounter = new byte[4]; byte[] rgbT = new byte[cbReturn]; uint counter = 0; for (int ib = 0; ib < rgbT.Length;) { // Increment counter -- up to 2^32 * sizeof(Hash) BinaryPrimitives.WriteUInt32BigEndian(rgbCounter, counter++); hasher.TransformBlock(rgbSeed, 0, rgbSeed.Length, rgbSeed, 0); hasher.TransformFinalBlock(rgbCounter, 0, 4); Debug.Assert(hasher.Hash != null); byte[] hash = hasher.Hash; hasher.Initialize(); Buffer.BlockCopy(hash, 0, rgbT, ib, Math.Min(rgbT.Length - ib, hash.Length)); ib += hasher.Hash.Length; } return(rgbT); } }
public void Dispose() { if (_hashAlgorithm != null) { _hashAlgorithm.Dispose(); _hashAlgorithm = null; } }
public void Dispose() { if (hashAlgorithm != null) { hashAlgorithm.Dispose(); hashAlgorithm = null; } }
public void HashAndVerify_Success() { string? content = File.ReadAllText("CryptoTest.txt"); HashAlgorithm?algorithm = HashAlgorithm.Create("SHA256"); string? hash = Cryptography.GetHash(algorithm, content); Assert.NotNull(hash); Assert.NotEmpty(hash); Assert.True(Cryptography.VerifyHash(algorithm, content, hash)); }
public void HashAndVerify_Fail() { string? content = File.ReadAllText("CryptoTest.txt"); HashAlgorithm?algorithm = HashAlgorithm.Create("SHA256"); string? hash = Cryptography.GetHash(algorithm, content); string?reverseContent = content.ToArray().Reverse().ToString(); string?hash2 = Cryptography.GetHash(algorithm, reverseContent); Assert.False(Cryptography.VerifyHash(algorithm, content, hash2)); Assert.False(Cryptography.VerifyHash(algorithm, reverseContent, hash)); }
public bool Parse(string challenge) { parser = new AuthDigestHeaderParser(challenge); if (!parser.Parse()) { return(false); } // build the hash object (only MD5 is defined in RFC2617) if ((parser.Algorithm == null) || (parser.Algorithm.StartsWith("MD5", StringComparison.OrdinalIgnoreCase))) { hash = MD5.Create(); } return(true); }
/// <summary> /// 获取Hash后的字节数组 /// </summary> /// <param name="type">哈希类型</param> /// <param name="key">key</param> /// <param name="bytes">原字节数组</param> /// <returns></returns> public static byte[]? GetHashedBytes(this IHashGenerater _, HashType type, byte[] bytes, byte[]?key) { if (null == bytes) { return(bytes); } HashAlgorithm?algorithm = null; try { if (key == null) { algorithm = type switch { HashType.MD5 => MD5.Create(), HashType.SHA1 => SHA1.Create(), HashType.SHA256 => SHA256.Create(), HashType.SHA384 => SHA384.Create(), HashType.SHA512 => SHA512.Create(), _ => MD5.Create(), }; } else { algorithm = type switch { HashType.MD5 => new HMACMD5(key), HashType.SHA1 => new HMACSHA1(key), HashType.SHA256 => new HMACSHA256(key), HashType.SHA384 => new HMACSHA384(key), HashType.SHA512 => new HMACSHA512(key), _ => new HMACMD5(key), }; } return(algorithm.ComputeHash(bytes)); } finally { algorithm?.Dispose(); } }
protected override void InnerDispose() { try { if (_hasher != null) { if (_result == null && _onResult != null) { FinishHashing(); } _hasher.Dispose(); } } finally { _hasher = null; base.InnerDispose(); } }
/// <summary> /// Get the hash for an input. /// </summary> /// <param name="hashAlgorithm">The hash algorithm to use.</param> /// <param name="input">The content to hash.</param> /// <returns>A string hash.</returns> public static string GetHash(HashAlgorithm?hashAlgorithm, string?input) { ArgumentNullException.ThrowIfNull(hashAlgorithm); if (string.IsNullOrWhiteSpace(input)) { throw new ArgumentNullException(nameof(input)); } // Convert the input string to a byte array and compute the hash. byte[] data = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input)); // Loop through each byte of the hashed data and format each one as a hexadecimal string. var sBuilder = new StringBuilder(); for (int d = 0; d < data.Length; d++) { sBuilder.Append(data[d].ToString("x2")); } return(sBuilder.ToString()); }
private static string GetCrlFileName(SafeX509Handle cert, string crlUrl) { // X509_issuer_name_hash returns "unsigned long", which is marshalled as ulong. // But it only sets 32 bits worth of data, so force it down to uint just... in case. ulong persistentHashLong = Interop.Crypto.X509IssuerNameHash(cert); if (persistentHashLong == 0) { Interop.Crypto.ErrClearError(); } uint persistentHash = unchecked ((uint)persistentHashLong); if (ts_urlHash == null) { ts_urlHash = SHA256.Create(); } Span <byte> hash = stackalloc byte[256 >> 3]; // Endianness isn't important, it just needs to be consistent. // (Even if the same storage was used for two different endianness systems it'd stabilize at two files). ReadOnlySpan <byte> utf16Url = MemoryMarshal.AsBytes(crlUrl.AsSpan()); if (!ts_urlHash.TryComputeHash(utf16Url, hash, out int written) || written != hash.Length) { Debug.Fail("TryComputeHash failed or produced an incorrect length output"); throw new CryptographicException(); } uint urlHash = MemoryMarshal.Read <uint>(hash); // OpenSSL's hashed filename algorithm is the 8-character hex version of the 32-bit value // of X509_issuer_name_hash (or X509_subject_name_hash, depending on the context). // // We mix in an 8-character hex version of the "left"-most bytes of a hash of the URL to // disambiguate when one Issuing Authority separates their revocation across independent CRLs. return($"{persistentHash:x8}.{urlHash:x8}.crl"); }
public async Task HashAndVerify_TwoFilesAsync() { string?tempFilename = Path.GetTempFileName(); try { HashAlgorithm?algorithm = HashAlgorithm.Create("SHA256"); FileStream?tempFile = File.Create(tempFilename); FileInfo?fileInfo1 = new("CryptoTest.txt"); FileInfo?fileInfo2 = new(tempFilename); string?content1 = File.ReadAllText(fileInfo1.FullName); // Make the second file identical except for an additional newline character. byte[]? buffer = Encoding.UTF8.GetBytes($"{content1}{Environment.NewLine}"); await tempFile.WriteAsync(buffer.AsMemory(0, buffer.Length)); await tempFile.FlushAsync(); tempFile.Close(); string?hash1 = Cryptography.GetHashForFile(algorithm, fileInfo1); string?hash2 = Cryptography.GetHashForFile(algorithm, fileInfo2); Assert.NotEqual(hash1, hash2); Assert.True(Cryptography.VerifyHashForFile(algorithm, fileInfo1, hash1)); Assert.True(Cryptography.VerifyHashForFile(algorithm, fileInfo2, hash2)); Assert.False(Cryptography.VerifyHashForFile(algorithm, fileInfo1, hash2)); Assert.False(Cryptography.VerifyHashForFile(algorithm, fileInfo2, hash1)); } finally { File.Delete(tempFilename); } }
/// <summary> /// Creates an instance of name based RFC4122 UUID generator. /// Either Version-3 (MD5 hashing) or Version-5 (SHA-1 hashing) variant is instantiated based on <paramref name="hashType"/>. /// </summary> /// <param name="hashType">Hashing algorithm type be used (MD5 or SHA-1)</param> public NameBasedGenerator(HashType hashType) { _hashAlgorithm = hashType == HashType.Md5 ? (HashAlgorithm)MD5.Create() : SHA1.Create(); _version = hashType == HashType.Md5 ? UUIDVersion.NameBasedWithMd5 : UUIDVersion.NamedBasedWithSha1; }
public CreateHashBucket(Bucket inner, HashAlgorithm hasher) : base(inner) { _hasher = hasher ?? throw new ArgumentNullException(nameof(hasher)); }
async Task AuthenticateSASL(List <string> mechanisms, string username, bool async, CancellationToken cancellationToken = default) { // At the time of writing PostgreSQL only supports SCRAM-SHA-256 and SCRAM-SHA-256-PLUS var supportsSha256 = mechanisms.Contains("SCRAM-SHA-256"); var supportsSha256Plus = mechanisms.Contains("SCRAM-SHA-256-PLUS"); if (!supportsSha256 && !supportsSha256Plus) { throw new NpgsqlException("No supported SASL mechanism found (only SCRAM-SHA-256 and SCRAM-SHA-256-PLUS are supported for now). " + "Mechanisms received from server: " + string.Join(", ", mechanisms)); } var mechanism = string.Empty; var cbindFlag = string.Empty; var cbind = string.Empty; var successfulBind = false; if (supportsSha256Plus) { var sslStream = (SslStream)_stream; if (sslStream.RemoteCertificate is null) { Log.Warn("Remote certificate null, falling back to SCRAM-SHA-256"); } else { using var remoteCertificate = new X509Certificate2(sslStream.RemoteCertificate); // Checking for hashing algorithms HashAlgorithm?hashAlgorithm = null; var algorithmName = remoteCertificate.SignatureAlgorithm.FriendlyName; if (algorithmName is null) { Log.Warn("Signature algorithm was null, falling back to SCRAM-SHA-256"); } else if (algorithmName.StartsWith("sha1", StringComparison.OrdinalIgnoreCase) || algorithmName.StartsWith("md5", StringComparison.OrdinalIgnoreCase) || algorithmName.StartsWith("sha256", StringComparison.OrdinalIgnoreCase)) { hashAlgorithm = SHA256.Create(); } else if (algorithmName.StartsWith("sha384", StringComparison.OrdinalIgnoreCase)) { hashAlgorithm = SHA384.Create(); } else if (algorithmName.StartsWith("sha512", StringComparison.OrdinalIgnoreCase)) { hashAlgorithm = SHA512.Create(); } else { Log.Warn($"Support for signature algorithm {algorithmName} is not yet implemented, falling back to SCRAM-SHA-256"); } if (hashAlgorithm != null) { using var _ = hashAlgorithm; // RFC 5929 mechanism = "SCRAM-SHA-256-PLUS"; // PostgreSQL only supports tls-server-end-point binding cbindFlag = "p=tls-server-end-point"; // SCRAM-SHA-256-PLUS depends on using ssl stream, so it's fine var cbindFlagBytes = Encoding.UTF8.GetBytes($"{cbindFlag},,"); var certificateHash = hashAlgorithm.ComputeHash(remoteCertificate.GetRawCertData()); var cbindBytes = cbindFlagBytes.Concat(certificateHash).ToArray(); cbind = Convert.ToBase64String(cbindBytes); successfulBind = true; IsScramPlus = true; } } } if (!successfulBind && supportsSha256) { mechanism = "SCRAM-SHA-256"; // We can get here if PostgreSQL supports only SCRAM-SHA-256 or there was an error while binding to SCRAM-SHA-256-PLUS // So, we set 'n' (client does not support binding) if there was an error while binding // or 'y' (client supports but server doesn't) in other case cbindFlag = supportsSha256Plus ? "n" : "y"; cbind = supportsSha256Plus ? "biws" : "eSws"; successfulBind = true; IsScram = true; } if (!successfulBind) { // We can get here if PostgreSQL supports only SCRAM-SHA-256-PLUS but there was an error while binding to it throw new NpgsqlException("Unable to bind to SCRAM-SHA-256-PLUS, check logs for more information"); } var passwd = GetPassword(username) ?? throw new NpgsqlException($"No password has been provided but the backend requires one (in SASL/{mechanism})"); // Assumption: the write buffer is big enough to contain all our outgoing messages var clientNonce = GetNonce(); await WriteSASLInitialResponse(mechanism, PGUtil.UTF8Encoding.GetBytes($"{cbindFlag},,n=*,r={clientNonce}"), async, cancellationToken); await Flush(async, cancellationToken); var saslContinueMsg = Expect <AuthenticationSASLContinueMessage>(await ReadMessage(async), this); if (saslContinueMsg.AuthRequestType != AuthenticationRequestType.AuthenticationSASLContinue) { throw new NpgsqlException("[SASL] AuthenticationSASLContinue message expected"); } var firstServerMsg = AuthenticationSCRAMServerFirstMessage.Load(saslContinueMsg.Payload); if (!firstServerMsg.Nonce.StartsWith(clientNonce)) { throw new NpgsqlException("[SCRAM] Malformed SCRAMServerFirst message: server nonce doesn't start with client nonce"); } var saltBytes = Convert.FromBase64String(firstServerMsg.Salt); var saltedPassword = Hi(passwd.Normalize(NormalizationForm.FormKC), saltBytes, firstServerMsg.Iteration); var clientKey = HMAC(saltedPassword, "Client Key"); byte[] storedKey; using (var sha256 = SHA256.Create()) storedKey = sha256.ComputeHash(clientKey); var clientFirstMessageBare = $"n=*,r={clientNonce}"; var serverFirstMessage = $"r={firstServerMsg.Nonce},s={firstServerMsg.Salt},i={firstServerMsg.Iteration}"; var clientFinalMessageWithoutProof = $"c={cbind},r={firstServerMsg.Nonce}"; var authMessage = $"{clientFirstMessageBare},{serverFirstMessage},{clientFinalMessageWithoutProof}"; var clientSignature = HMAC(storedKey, authMessage); var clientProofBytes = Xor(clientKey, clientSignature); var clientProof = Convert.ToBase64String(clientProofBytes); var serverKey = HMAC(saltedPassword, "Server Key"); var serverSignature = HMAC(serverKey, authMessage); var messageStr = $"{clientFinalMessageWithoutProof},p={clientProof}"; await WriteSASLResponse(Encoding.UTF8.GetBytes(messageStr), async, cancellationToken); await Flush(async, cancellationToken); var saslFinalServerMsg = Expect <AuthenticationSASLFinalMessage>(await ReadMessage(async), this); if (saslFinalServerMsg.AuthRequestType != AuthenticationRequestType.AuthenticationSASLFinal) { throw new NpgsqlException("[SASL] AuthenticationSASLFinal message expected"); } var scramFinalServerMsg = AuthenticationSCRAMServerFinalMessage.Load(saslFinalServerMsg.Payload); if (scramFinalServerMsg.ServerSignature != Convert.ToBase64String(serverSignature)) { throw new NpgsqlException("[SCRAM] Unable to verify server signature"); } var okMsg = Expect <AuthenticationRequestMessage>(await ReadMessage(async), this); if (okMsg.AuthRequestType != AuthenticationRequestType.AuthenticationOk) { throw new NpgsqlException("[SASL] Expected AuthenticationOK message"); }
/// <summary> /// Verify the hash of a file. /// </summary> /// <param name="hashAlgorithm">The hash algorithm to use.</param> /// <param name="fileInfo">The file to hash.</param> /// <param name="hash">The expected hash.</param> /// <returns>True if the hashes match, otherwise false.</returns> public static bool VerifyHashForFile(HashAlgorithm?hashAlgorithm, FileInfo fileInfo, string hash) => VerifyHash(hashAlgorithm, File.ReadAllText(fileInfo.FullName), hash);
public SM2DeriveBytes(ReadOnlySpan <byte> key, HashAlgorithm?hash = null) { _key = new byte[key.Length + 4]; _hasher = hash ?? new SM3(); key.CopyTo(_key); }
/// <summary> /// Computes the hash of the specified buffer and checks for a match to an expected hash. /// </summary> /// <param name="cryptoProvider">The crypto provider.</param> /// <param name="data">The data to hash.</param> /// <param name="expectedHash">The expected hash.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <returns> /// <c>true</c> if the hashes came out equal; <c>false</c> otherwise. /// </returns> internal static bool IsHashMatchWithTolerantHashAlgorithm(this CryptoSettings cryptoProvider, byte[] data, byte[] expectedHash, HashAlgorithm? hashAlgorithm) { Requires.NotNull(cryptoProvider, "cryptoProvider"); Requires.NotNull(data, "data"); Requires.NotNull(expectedHash, "expectedHash"); if (!hashAlgorithm.HasValue) { hashAlgorithm = Utilities.GuessHashAlgorithmFromLength(expectedHash.Length); } var hasher = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(hashAlgorithm.Value); byte[] actualHash = hasher.HashData(data); return Utilities.AreEquivalent(expectedHash, actualHash); }
/// <summary> /// Verify the hash for a certain input. /// </summary> /// <param name="hashAlgorithm">The hash algorithm to use.</param> /// <param name="input">The content to hash.</param> /// <param name="hash">The expected hash.</param> /// <returns>True if the hashes match, otherwise false.</returns> public static bool VerifyHash(HashAlgorithm?hashAlgorithm, string?input, string?hash) => StringComparer.OrdinalIgnoreCase.Compare(GetHash(hashAlgorithm, input), hash) == 0;
public HashingStreamEx(Stream sBaseStream, bool bWriting, HashAlgorithm?hashAlgorithm)
/// <summary> /// Return an output stream which will encrypt the data as it is written to it. /// </summary> protected override IPacketWriter Open() { var writer = base.Open(); if (cOut != null) { throw new InvalidOperationException("generator already in open state"); } // TODO: Do we want compatibility with old PGP? (IDEA + no password iirc) if (methods.Count == 0) { throw new InvalidOperationException("No encryption methods specified"); } var c = PgpUtilities.GetSymmetricAlgorithm(defAlgorithm); if (methods.Count == 1 && methods[0] is PbeMethod) { PbeMethod m = (PbeMethod)methods[0]; c.Key = m.GetKey(); writer.WritePacket(m.GetSessionInfoPacket()); } else { c.GenerateKey(); byte[] sessionInfo = CreateSessionInfo(defAlgorithm, c.Key); foreach (EncMethod m in methods) { writer.WritePacket(m.GetSessionInfoPacket(sessionInfo)); } } try { if (withIntegrityPacket) { pOut = writer.GetPacketStream(new SymmetricEncIntegrityPacket()); } else { pOut = writer.GetPacketStream(new SymmetricEncDataPacket()); } int blockSize = (c.BlockSize + 7) / 8; byte[] inLineIv = new byte[blockSize * 2]; // Aligned to block size RandomNumberGenerator.Fill(inLineIv.AsSpan(0, blockSize)); inLineIv[blockSize] = inLineIv[blockSize - 2]; inLineIv[blockSize + 1] = inLineIv[blockSize - 1]; ICryptoTransform encryptor; c.IV = new byte[blockSize]; if (withIntegrityPacket) { encryptor = c.CreateEncryptor(); } else { encryptor = c.CreateEncryptor(); var encryptedInlineIv = encryptor.TransformFinalBlock(inLineIv, 0, inLineIv.Length); pOut.Write(encryptedInlineIv.AsSpan(0, blockSize + 2)); c.IV = encryptedInlineIv.AsSpan(2, blockSize).ToArray(); encryptor = c.CreateEncryptor(); } Stream myOut = cOut = new CryptoStream(pOut, new ZeroPaddedCryptoTransform(encryptor), CryptoStreamMode.Write); if (withIntegrityPacket) { digest = SHA1.Create(); myOut = digestOut = new CryptoStream(new FilterStream(myOut), digest, CryptoStreamMode.Write); myOut.Write(inLineIv, 0, blockSize + 2); } return(writer.CreateNestedWriter(new WrappedGeneratorStream(myOut, _ => Close()))); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } }
public unsafe X509Certificate2 GenerateCertificate(X509Certificate2 issuingCertificate, PrivateKey privateKey, X500DistinguishedName dn, string[] dnsNames, IPAddress[] ipAddresses = null, HashAlgorithm?signatureAlgorithm = null, DateTime?notBefore = null, DateTime?notAfter = null) { if (!issuingCertificate.HasPrivateKey) { throw new ArgumentException("Issuing certificate must have a private key.", nameof(issuingCertificate)); } IntPtr basicEncodedDataPtr = IntPtr.Zero, certExtensionPtr = IntPtr.Zero; var serialNumber = new byte[16]; var rng = RandomNumberGenerator.Create(); rng.GetNonZeroBytes(serialNumber); serialNumber[15] &= 0x7F; fixed(byte *dnPtr = dn.RawData, issuerDnPtr = issuingCertificate.SubjectName.RawData, serialNumberPtr = serialNumber) { try { var blob = new NATIVE_CRYPTOAPI_BLOB { cbData = (uint)dn.RawData.Length, pbData = dnPtr }; var signingSignatureAlgorithmIdentifier = new CRYPT_ALGORITHM_IDENTIFIER { pszObjId = issuingCertificate.SignatureAlgorithm.Value }; using (var signingKey = ExtractKey(issuingCertificate)) { var signingAlgorithmIdentifier = new CRYPT_ALGORITHM_IDENTIFIER { pszObjId = signatureAlgorithm != null?HashAlgorithmToSignatureAlgorithm(signingKey, signatureAlgorithm.Value) : issuingCertificate.SignatureAlgorithm.Value }; using (PublicKeyInfo publicKey = privateKey.ToPublicKey(), signingPublicKey = signingKey.ToPublicKey()) { using (var extensions = new MarshalX509ExtensionCollection()) { using (extensions.Freeze()) { var usage = X509KeyUsageFlags.DigitalSignature; if (privateKey.AlgorithmGroup == AlgorithmGroup.RSA) { //Key encipherment is not valid for DSA/ECDSA usage |= X509KeyUsageFlags.KeyEncipherment; } extensions.Add(new X509BasicConstraintsExtension(false, false, 0, true)); extensions.Add(new X509KeyUsageExtension(usage, true)); extensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid(OIDs.EKU_SERVER) }, false)); extensions.Add(new X509SubjectAlternativeNameExtension(DnsAltNamesFromArray(dnsNames, ipAddresses ?? new IPAddress[0]), false)); using (var sha1 = new SHA1CryptoServiceProvider()) { var issuingKeyId = sha1.ComputeHash(signingPublicKey.Key); extensions.Add(new X509SubjectKeyIdentifierExtension(sha1.ComputeHash(publicKey.Key), false)); extensions.Add(new X509AuthorityKeyIdentifierExtension(issuingKeyId, null)); } } var certInfo = new CERT_INFO(); certInfo.Subject = blob; certInfo.SerialNumber = new NATIVE_CRYPTOAPI_BLOB { cbData = (uint)serialNumber.Length, pbData = serialNumberPtr }; certInfo.SubjectPublicKeyInfo = publicKey.PublicKey; certInfo.dwVersion = CertificateVersion.CERT_V3; certInfo.Issuer = new NATIVE_CRYPTOAPI_BLOB { cbData = (uint)issuingCertificate.SubjectName.RawData.Length, pbData = issuerDnPtr }; certInfo.SignatureAlgorithm = signingAlgorithmIdentifier; certInfo.NotAfter = FileTimeHelper.ToFileTimeStructureUtc(notAfter ?? DateTime.Now.AddHours(-1).AddYears(5)); certInfo.NotBefore = FileTimeHelper.ToFileTimeStructureUtc(notBefore ?? DateTime.Now.AddHours(-1)); certInfo.cExtension = extensions.Extensions.cExtension; certInfo.rgExtension = extensions.Extensions.rgExtension; var size = 0u; var CERT_INFO_TYPE = (IntPtr)2; if (!Crypt32.CryptSignAndEncodeCertificate(signingKey.Handle, signingKey.KeySpec, EncodingType.X509_ASN_ENCODING, CERT_INFO_TYPE, ref certInfo, ref signingSignatureAlgorithmIdentifier, IntPtr.Zero, IntPtr.Zero, ref size)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var buffer = Marshal.AllocHGlobal((int)size); if (!Crypt32.CryptSignAndEncodeCertificate(signingKey.Handle, signingKey.KeySpec, EncodingType.X509_ASN_ENCODING, CERT_INFO_TYPE, ref certInfo, ref signingSignatureAlgorithmIdentifier, IntPtr.Zero, buffer, ref size)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } const int CERT_KEY_PROV_INFO_PROP_ID = 2; var certificate = new X509Certificate2(SerializeCertificate(buffer, size)); var keyProvInfo = new CRYPT_KEY_PROV_INFO { cProvParam = 0, dwKeySpec = privateKey.KeySpec, dwProvType = privateKey.Handle.IsNCryptKey ? ProviderType.CNG : ProviderType.PROV_RSA_AES, pwszProvName = privateKey.ProviderName, dwFlags = 0, pwszContainerName = privateKey.Name }; if (!Crypt32.CertSetCertificateContextProperty(certificate.Handle, CERT_KEY_PROV_INFO_PROP_ID, 0u, ref keyProvInfo)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(new X509Certificate2(certificate)); } } } } finally { Marshal.FreeHGlobal(basicEncodedDataPtr); Marshal.FreeHGlobal(certExtensionPtr); } } }
private Stream GetDataStream(ReadOnlySpan <byte> sessionData, bool verifyIntegrity) { PgpSymmetricKeyAlgorithm keyAlgorithm = (PgpSymmetricKeyAlgorithm)sessionData[0]; if (keyAlgorithm == PgpSymmetricKeyAlgorithm.Null) { return(inputStream); } var key = sessionData.Slice(1); SymmetricAlgorithm encryptionAlgorithm = PgpUtilities.GetSymmetricAlgorithm(keyAlgorithm); var iv = new byte[(encryptionAlgorithm.BlockSize + 7) / 8]; byte[] keyArray = Array.Empty <byte>(); ICryptoTransform decryptor; var inlineIv = new byte[iv.Length * 2]; // Aligned to block size try { keyArray = key.ToArray(); decryptor = encryptionAlgorithm.CreateDecryptor(keyArray, iv); if (encryptedPacket is SymmetricEncDataPacket) { if (inputStream.ReadFully(inlineIv.AsSpan(0, iv.Length + 2)) < iv.Length + 2) { throw new EndOfStreamException(); } var decryptedInlineIv = decryptor.TransformFinalBlock(inlineIv, 0, inlineIv.Length); if (verifyIntegrity) { VerifyInlineIV(decryptedInlineIv.AsSpan(0, iv.Length), decryptedInlineIv.AsSpan(iv.Length, 2)); } // Perform reset according to the OpenPGP CFB rules decryptor = encryptionAlgorithm.CreateDecryptor(keyArray, inlineIv.AsSpan(2, iv.Length).ToArray()); } } finally { CryptographicOperations.ZeroMemory(keyArray.AsSpan()); } encStream = new CryptoStream( inputStream, new ZeroPaddedCryptoTransform(decryptor), CryptoStreamMode.Read); if (encryptedPacket is SymmetricEncIntegrityPacket) { hashAlgorithm = SHA1.Create(); tailEndCryptoTransform = new TailEndCryptoTransform(hashAlgorithm, hashAlgorithm.HashSize / 8); encStream = new CryptoStream(encStream, tailEndCryptoTransform, CryptoStreamMode.Read); if (encStream.ReadFully(inlineIv.AsSpan(0, iv.Length + 2)) < iv.Length + 2) { throw new EndOfStreamException(); } if (verifyIntegrity) { VerifyInlineIV(inlineIv.AsSpan(0, iv.Length), inlineIv.AsSpan(iv.Length, 2)); } } return(encStream); }
/// <summary> /// Get the hash for a file. /// </summary> /// <param name="hashAlgorithm">The hash algorithm to use.</param> /// <param name="fileInfo">The file to hash.</param> /// <returns>A string hash.</returns> public static string GetHashForFile(HashAlgorithm?hashAlgorithm, FileInfo fileInfo) => GetHash(hashAlgorithm, File.ReadAllText(fileInfo.FullName));