diff --git a/docs/core/compatibility/cryptography/10.0/openssl-macos-unsupported.md b/docs/core/compatibility/cryptography/10.0/openssl-macos-unsupported.md index c4840d1e52e3c..b3a61c0835ba6 100644 --- a/docs/core/compatibility/cryptography/10.0/openssl-macos-unsupported.md +++ b/docs/core/compatibility/cryptography/10.0/openssl-macos-unsupported.md @@ -46,7 +46,7 @@ If you're using OpenSSL-backed primitives without any specific intention of usin * `new ECDsaOpenSsl(...)` -> `ECDsa.Create(...)` * `new RSAOpenSsl(...)` -> `RSA.Create(...)` - has no functional equivalent on macOS. Consider using a different cryptographic primitive, such as , instead. + has no functional equivalent on macOS. ## Affected APIs diff --git a/docs/core/extensions/sslstream-best-practices.md b/docs/core/extensions/sslstream-best-practices.md index 63f23da8dfd3f..57f60832bcc06 100644 --- a/docs/core/extensions/sslstream-best-practices.md +++ b/docs/core/extensions/sslstream-best-practices.md @@ -20,7 +20,7 @@ Deferring the decision to the OS automatically uses the most recent version of T ## Select cipher suites -`SslStream` allows users to specify which cipher suites can be negotiated by the TLS handshake via the class. As with TLS versions, it's recommended to let the OS decide which are the best cipher suites to negotiate with, and, therefore, it's recommended to avoid using . +`SslStream` allows users to specify which cipher suites can be negotiated by the TLS handshake via the class. As with TLS versions, it's recommended to let the OS decide which are the best cipher suites to negotiate with, and avoid using unless you have a specific interoperability requirement. > [!NOTE] > is not supported on Windows and attempts to instantiate it will cause to be thrown. @@ -37,7 +37,7 @@ There are multiple ways that a server certificate can be passed to property. When the certificate is obtained by one of the other two ways, a instance is created internally by the implementation. Creating a involves building an which is a CPU intensive operation. It is more efficient to create a once and reuse it for multiple instances. -Reusing instances also enables additional features such us [TLS session resumption](https://datatracker.ietf.org/doc/html/rfc5077) on Linux servers. +Reusing instances also enables additional features such as [TLS session resumption](https://datatracker.ietf.org/doc/html/rfc5077) on Linux servers. ## Custom `X509Certificate` validation diff --git a/docs/framework/configure-apps/file-schema/wcf/sslstreamsecurity.md b/docs/framework/configure-apps/file-schema/wcf/sslstreamsecurity.md index e5429151cdc96..a3770fb855d77 100644 --- a/docs/framework/configure-apps/file-schema/wcf/sslstreamsecurity.md +++ b/docs/framework/configure-apps/file-schema/wcf/sslstreamsecurity.md @@ -22,6 +22,9 @@ Represents a custom binding element that supports channel security using an SSL sslProtocols="Ssl3|Tls|Tls11|Tls12" /> ``` +> [!IMPORTANT] +> The syntax shows the full historical enum surface for the `sslProtocols` attribute. For new configurations, don't enable `Ssl3`, `Tls`, or `Tls11`. Prefer OS defaults, or limit the configuration to modern TLS versions supported by your target platform. For more information, see [Transport Layer Security (TLS) best practices with the .NET Framework](../../../network-programming/tls.md). + ## Attributes and Elements The following sections describe attributes, child elements, and parent elements. @@ -31,7 +34,7 @@ Represents a custom binding element that supports channel security using an SSL |Attribute|Description| |---------------|-----------------| |requireClientCertificate|A Boolean value that specifies if a client certificate is required for this binding. The default is `false`.| -|sslProtocols|A SslProtocols enum flag value that specifies which SslProtocols are supported. The default is Ssl3|Tls|Tls11|Tls12.| +|sslProtocols|A SslProtocols enum flag value that specifies which SslProtocols are supported. The default is Ssl3|Tls|Tls11|Tls12. This historical default exists for compatibility and isn't recommended for new configurations.| ### Child Elements diff --git a/docs/framework/migration-guide/mitigation-tls-protocols.md b/docs/framework/migration-guide/mitigation-tls-protocols.md index 7695302dc86ce..7d6c38e3190ba 100644 --- a/docs/framework/migration-guide/mitigation-tls-protocols.md +++ b/docs/framework/migration-guide/mitigation-tls-protocols.md @@ -9,7 +9,7 @@ ms.assetid: 33f97d13-3022-43da-8b18-cdb5c88df9c2 --- # Mitigation: TLS Protocols -Starting with .NET Framework 4.6, the and classes are allowed to use one of the following three protocols: Tls1.0, Tls1.1, or Tls 1.2. The SSL3.0 protocol and RC4 cipher are not supported. +Starting with .NET Framework 4.6, the and classes no longer support the SSL 3.0 protocol or the RC4 cipher. ## Impact @@ -17,11 +17,11 @@ Starting with .NET Framework 4.6, the , , , , and . -- Any server-side app that cannot be upgraded to support Tls1.0, Tls1.1, or Tls 1.2.. +- Any server-side app that cannot be upgraded to support modern TLS configurations. ## Mitigation - The recommended mitigation is to upgrade the sever-side app to Tls1.0, Tls1.1, or Tls 1.2. If this is not feasible, or if client apps are broken, the class can be used to opt out of this feature in either of two ways: + The recommended mitigation is to upgrade the server-side app to support modern TLS configurations. If that isn't feasible, or if client apps are broken, the class can be used to opt out of this feature in either of two ways as a temporary compatibility workaround: - Programmatically, by using a code snippet like the following: @@ -36,7 +36,7 @@ Starting with .NET Framework 4.6, the ``` - Note, however, that opting out of the default behavior is not recommended, since it makes the application less secure. + Note, however, that opting out of the default behavior is not recommended, since it makes the application less secure. ## See also diff --git a/docs/framework/network-programming/tls.md b/docs/framework/network-programming/tls.md index 87edb79dcd544..4cf64f4ceb552 100644 --- a/docs/framework/network-programming/tls.md +++ b/docs/framework/network-programming/tls.md @@ -24,7 +24,7 @@ helpviewer_keywords: ## What is Transport Layer Security (TLS)? > [!WARNING] -> TLS 1.0 and 1.1 has been deprecated by [RFC8996](https://datatracker.ietf.org/doc/rfc8996/). This document covers TLS 1.2 and TLS 1.3 only. +> TLS 1.0 and TLS 1.1 have been deprecated by [RFC 8996](https://datatracker.ietf.org/doc/rfc8996/). This document covers TLS 1.2 and TLS 1.3 only. The Transport Layer Security (TLS) protocol is an industry latest version of the standard designed to help protect the privacy of information communicated over the Internet. [TLS 1.3](https://tools.ietf.org/html/rfc8446) is a standard that provides security improvements over previous versions. This article presents recommendations to secure .NET Framework applications that use the TLS protocol. @@ -53,11 +53,11 @@ For more information see [TLS protocol version support in Schannel](/windows/win ## Recommendations -- For TLS 1.3, target .NET Framework 4.8 or later. Check [Audit your code](#audit-your-code-and-make-code-changes) section how to verify your `target framework`. +- For TLS 1.3, target .NET Framework 4.8 or later. Check the [Audit your code](#audit-your-code-and-make-code-changes) section how to verify your `target framework`. - Do not specify the TLS version explicitly, i.e. don't use the method overloads of `SslStream` that take an explicit `SslProtocols` parameter. - That way your code will let the OS decide on the TLS version. - - If you must set , then set it to . That will also use OS default. - - If you must use the method overloads of `SslStream` that take an explicit `SslProtocols` parameter, then pass `SslProtocols.SystemDefault` as argument. That will also use OS default. + - If you must set , then set it to . That will also use the OS default. + - If you must use the method overloads of `SslStream` that take an explicit `SslProtocols` parameter, then pass `SslProtocols.SystemDefault` as argument. That will also use the OS default. - Perform a thorough code audit to verify you're not specifying a TLS or SSL version explicitly. > [!WARNING] @@ -70,7 +70,7 @@ When your app lets the OS choose the TLS version: This article explains how to enable the strongest security available for the version of .NET Framework that your app targets and runs on. When an app explicitly sets a security protocol and version, it opts out of any other alternative, and opts out of .NET Framework and OS default behavior. If you want your app to be able to negotiate a TLS 1.3 connection, explicitly setting to a lower TLS version prevents a TLS 1.3 connection. -If you can't avoid specifying a protocol version explicitly, we strongly recommend that you specify TLS 1.2 or TLS 1.3 (which is `currently considered secure`). For guidance on identifying and removing TLS 1.0 dependencies, download the [Solving the TLS 1.0 Problem](https://www.microsoft.com/download/details.aspx?id=55266) white paper. +If you can't avoid specifying a protocol version explicitly, include only those legacy versions that you absolutely need, and omit modern default versions only when they cause compatibility issues. For guidance on identifying and removing TLS 1.0 dependencies, download the [Solving the TLS 1.0 Problem](https://www.microsoft.com/download/details.aspx?id=55266) white paper. WCF supports TLS 1.2 as the default in .NET Framework 4.7. Starting with .NET Framework 4.7.1, WCF defaults to the operating system configured version. If an application is explicitly configured with `SslProtocols.None`, WCF uses the operating system default setting when using the NetTcp transport. @@ -139,7 +139,7 @@ Because the defaults to the security protocol and version chosen by the OS. To get the default OS best choice, if possible, don't use the method overloads of that take an explicit parameter. Otherwise, pass . We recommend that you don't use ; setting `SslProtocols.Default` forces the use of SSL 3.0 /TLS 1.0 and prevents TLS 1.2. + defaults to the security protocol and version chosen by the OS. To get the default OS best choice, if possible, don't use the method overloads of that take an explicit parameter. Otherwise, pass . We recommend that you don't use ; setting `SslProtocols.Default` forces the use of SSL 3.0 /TLS 1.0 and prevents negotiation of newer versions. Don't set a value for the property (for HTTP networking). @@ -160,7 +160,7 @@ If you're targeting 4.7.1, WCF is configured to allow the OS to choose the best - In your application configuration file. - **Or**, in your application in the source code. -By default, .NET Framework 4.7 and later versions are configured to use TLS 1.2 and allow connections using TLS 1.1 or TLS 1.0. Configure WCF to allow the OS to choose the best security protocol by configuring your binding to use . You can set this on . `SslProtocols.None` can be accessed from . `NetTcpSecurity.Transport` can be accessed from . +By default, .NET Framework 4.7 and later versions are configured to use TLS 1.2 and allow connections using TLS 1.1 or TLS 1.0. Don't rely on those older protocols. Configure WCF to allow the OS to choose the best security protocol by configuring your binding to use . You can set this on . `SslProtocols.None` can be accessed from . `NetTcpSecurity.Transport` can be accessed from . If you're using a custom binding: @@ -171,7 +171,7 @@ If you're **not** using a custom binding **and** you're setting your WCF binding #### Using Message Security with certificate credentials -.NET Framework 4.7 and later versions by default use the protocol specified in the property. When the [AppContextSwitch](../configure-apps/file-schema/runtime/appcontextswitchoverrides-element.md) `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` is set to `true`, WCF chooses the best protocol, up to TLS 1.0. +.NET Framework 4.7 and later versions by default use the protocol specified in the property. When the [AppContextSwitch](../configure-apps/file-schema/runtime/appcontextswitchoverrides-element.md) `Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols` is set to `true`, WCF chooses the best protocol, up to TLS 1.0. That compatibility path is for legacy scenarios and doesn't satisfy current security guidance. #### [.NET Framework 4.6.2 and earlier](#tab/462-minus) @@ -191,7 +191,7 @@ The switches have the same effect whether you're doing HTTP networking ( classes use the Secure Sockets Layer (SSL) to encrypt the connection for several network protocols. +The classes use Transport Layer Security (TLS), historically referred to as Secure Sockets Layer (SSL), to encrypt the connection for several network protocols. For http connections, the and classes use SSL to communicate with web hosts that support SSL. The decision to use SSL is made by the class, based on the URI it is given. If the URI begins with "https:", SSL is used; if the URI begins with "http:", an unencrypted connection is used. diff --git a/docs/fundamentals/code-analysis/quality-rules/ca5358.md b/docs/fundamentals/code-analysis/quality-rules/ca5358.md index 664c8c72f1ed5..6ef4e94f16f1c 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca5358.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca5358.md @@ -35,6 +35,7 @@ These modes are vulnerable to attacks and may cause exposure of sensitive inform ## How to fix violations - Use only approved modes (, ). +- If you use CBC-based encryption, validate integrity before you decrypt. For more information, see [Timing vulnerabilities with CBC-mode symmetric decryption using padding](../../../standard/security/vulnerabilities-cbc-mode.md). ## When to suppress warnings diff --git a/docs/fundamentals/code-analysis/quality-rules/ca5361.md b/docs/fundamentals/code-analysis/quality-rules/ca5361.md index c49f5796a0dcb..02e43e70d182f 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca5361.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca5361.md @@ -40,7 +40,7 @@ Setting `Switch.System.Net.DontEnableSchUseStrongCrypto` to `true` weakens the c ## When to suppress warnings -You can suppress this warning if you need to connect to a legacy service that can't be upgraded to use secure TLS configurations. +You can suppress this warning only if you need to connect to a legacy service that does not support modern TLS versions. Treat that suppression as a temporary compatibility measure. ## Suppress a warning diff --git a/docs/fundamentals/code-analysis/quality-rules/ca5387.md b/docs/fundamentals/code-analysis/quality-rules/ca5387.md index 5637c9177094c..ca144313e77e4 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca5387.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca5387.md @@ -34,6 +34,12 @@ This rule is similar to [CA5388](ca5388.md), but analysis determines that the it Set the iteration count greater than or equal with 100,000 before calling . +> [!TIP] +> While the analyzer enforces a minimum of 100,000 iterations, this threshold might not keep pace with hardware improvements. [NIST SP 800-132](https://csrc.nist.gov/pubs/sp/800/132/final) recommends selecting an iteration count as high as your environment can tolerate, and increasing it periodically as computing power grows. However, excessively high iteration counts increase CPU cost per authentication attempt, which can be exploited for denial-of-service attacks. Choose a value that balances security with acceptable latency for your application. + +> [!TIP] +> Remember that you need to save the iteration count (or a version/scheme identifier that represents it) used to produce the original output so that you can specify the same value again when trying to reproduce the value. + ## When to suppress warnings It's safe to suppress a warning if you need to use a smaller iteration count for compatibility with existing data. diff --git a/docs/fundamentals/code-analysis/quality-rules/ca5388.md b/docs/fundamentals/code-analysis/quality-rules/ca5388.md index e05228ffd8854..b976dc017b620 100644 --- a/docs/fundamentals/code-analysis/quality-rules/ca5388.md +++ b/docs/fundamentals/code-analysis/quality-rules/ca5388.md @@ -34,6 +34,12 @@ This rule is similar to [CA5387](ca5387.md), but analysis can't determine if the Set the iteration count greater than or equal with 100k before calling explicitly. +> [!TIP] +> While the analyzer enforces a minimum of 100,000 iterations, this threshold might not keep pace with hardware improvements. [NIST SP 800-132](https://csrc.nist.gov/pubs/sp/800/132/final) recommends selecting an iteration count as high as your environment can tolerate, and increasing it periodically as computing power grows. However, excessively high iteration counts increase CPU cost per authentication attempt, which can be exploited for denial-of-service attacks. Choose a value that balances security with acceptable latency for your application. + +> [!TIP] +> Remember that you need to save the iteration count (or a version/scheme identifier that represents it) used to produce the original output so that you can specify the same value again when trying to reproduce the value. + ## When to suppress warnings It's safe to suppress warnings from this rule if: diff --git a/docs/fundamentals/syslib-diagnostics/syslib0033.md b/docs/fundamentals/syslib-diagnostics/syslib0033.md index 1c810a06bf3a9..170db08c9762e 100644 --- a/docs/fundamentals/syslib-diagnostics/syslib0033.md +++ b/docs/fundamentals/syslib-diagnostics/syslib0033.md @@ -11,7 +11,9 @@ The instead. +If you need compatibility with an existing CryptoAPI-based format or protocol, use . + +For new development, use a newer, standardized Key Derivation Function (KDF). ## Suppress a warning diff --git a/docs/fundamentals/syslib-diagnostics/syslib0041.md b/docs/fundamentals/syslib-diagnostics/syslib0041.md index e073b5317f094..fda02b2fe288a 100644 --- a/docs/fundamentals/syslib-diagnostics/syslib0041.md +++ b/docs/fundamentals/syslib-diagnostics/syslib0041.md @@ -19,9 +19,13 @@ The following constructor ## Workaround -Use a different constructor overload where you can explicitly specify the iteration count (the default is 1000) and hash algorithm name (the default is ). +Use a different constructor overload where you can explicitly specify the iteration count and hash algorithm name. -If you're using the default iteration count or default hash algorithm, consider moving to more secure values—that is, a larger iteration count or a newer hash algorithm. +For compatibility with existing values specify an iteration count of 1000 and a hash algorithm of . +When generating new values, use an iteration count and hash algorithm consistent with your desired security properties. + +> [!TIP] +> For information on choosing an iteration count, see [NIST SP 800-132](https://csrc.nist.gov/pubs/sp/800/132/final) Appendix A.2.2. ## Suppress a warning diff --git a/docs/standard/security/cross-platform-cryptography.md b/docs/standard/security/cross-platform-cryptography.md index 78c7f7564c417..6d95d4d54c245 100644 --- a/docs/standard/security/cross-platform-cryptography.md +++ b/docs/standard/security/cross-platform-cryptography.md @@ -19,6 +19,9 @@ The dependency on OS libraries also means that .NET apps can only use cryptograp This article assumes you have a working familiarity with cryptography in .NET. For more information, see [.NET Cryptography Model](cryptography-model.md) and [.NET Cryptographic Services](cryptographic-services.md). +> [!IMPORTANT] +> The following tables show platform support, not recommendations for new development. Some algorithms and modes remain available for standards conformance and backward compatibility even though current guidance deprecates them for new systems. + ## Hash and Message Authentication Algorithms All hash algorithm and hash-based message authentication (HMAC) classes, including the `*Managed` classes, defer to the OS libraries with the exception of .NET on Browser WASM. In Browser WASM, SHA-1, SHA-2-256, SHA-2-384, SHA-2-512 and the HMAC equivalents are implemented using managed code. diff --git a/docs/standard/security/cryptographic-services.md b/docs/standard/security/cryptographic-services.md index f0b4a955fa7c9..587d15ed14d2c 100644 --- a/docs/standard/security/cryptographic-services.md +++ b/docs/standard/security/cryptographic-services.md @@ -65,9 +65,9 @@ Secret-key encryption algorithms use a single secret key to encrypt and decrypt Secret-key encryption is also referred to as symmetric encryption because the same key is used for encryption and decryption. Secret-key encryption algorithms are very fast (compared with public-key algorithms) and are well suited for performing cryptographic transformations on large streams of data. Asymmetric encryption algorithms such as RSA are limited mathematically in how much data they can encrypt. Symmetric encryption algorithms do not generally have those problems. -A type of secret-key algorithm called a block cipher is used to encrypt one block of data at a time. Block ciphers such as Data Encryption Standard (DES), TripleDES, and Advanced Encryption Standard (AES) cryptographically transform an input block of *n* bytes into an output block of encrypted bytes. If you want to encrypt or decrypt a sequence of bytes, you have to do it block by block. Because *n* is small (8 bytes for DES and TripleDES; 16 bytes [the default], 24 bytes, or 32 bytes for AES), data values that are larger than *n* have to be encrypted one block at a time. Data values that are smaller than *n* have to be expanded to *n* in order to be processed. +A type of secret-key algorithm called a block cipher is used to encrypt one block of data at a time. Block ciphers such as Data Encryption Standard (DES), TripleDES, and Advanced Encryption Standard (AES) cryptographically transform an input block of *n* bytes into an output block of encrypted bytes. If you want to encrypt or decrypt a sequence of bytes, you have to do it block by block. Because *n* is small (8 bytes for DES and TripleDES; 16 bytes [the default], 24 bytes, or 32 bytes for AES), data values that are larger than *n* have to be encrypted one block at a time. Data values that are smaller than *n* have to be expanded to *n* in order to be processed. There are multiple algorithms for handling the sequence of blocks, known as the "block cipher mode of operation", "block cipher chain mode" or just "chain mode". -One simple form of block cipher is called the electronic codebook (ECB) mode. ECB mode is not considered secure, because it does not use an initialization vector to initialize the first plaintext block. For a given secret key *k*, a simple block cipher that does not use an initialization vector will encrypt the same input block of plaintext into the same output block of ciphertext. Therefore, if you have duplicate blocks in your input plaintext stream, you will have duplicate blocks in your output ciphertext stream. These duplicate output blocks alert unauthorized users to the weak encryption used the algorithms that might have been employed, and the possible modes of attack. The ECB cipher mode is therefore quite vulnerable to analysis, and ultimately, key discovery. +One simple form of block cipher mode is called Electronic CodeBook (ECB). ECB mode is not considered secure, because it does not use an initialization vector to initialize the first plaintext block. For a given secret key *k*, a simple block cipher that does not use an initialization vector will encrypt the same input block of plaintext into the same output block of ciphertext. Therefore, if you have duplicate blocks in your input plaintext stream, you will have duplicate blocks in your output ciphertext stream. These duplicate output blocks alert unauthorized users to the weak encryption used the algorithms that might have been employed, and the possible modes of attack. The ECB cipher mode is therefore quite vulnerable to analysis, and ultimately, key discovery. The block cipher classes that are provided in the base class library use a default chaining mode called cipher-block chaining (CBC), although you can change this default if you want. @@ -119,7 +119,7 @@ The following list offers comparisons between public-key and secret-key cryptogr - -RSA allows both encryption and signing, but DSA can be used only for signing. DSA is not as secure as RSA, and we recommend RSA. Diffie-Hellman can be used only for key generation. In general, public-key algorithms are more limited in their uses than private-key algorithms. +RSA allows both encryption and signing, but DSA can be used only for signing. DSA is not as secure as RSA, and we recommend RSA. Diffie-Hellman can be used only for key generation. In general, public-key algorithms are more limited in their uses than secret-key algorithms. ## Digital Signatures @@ -170,13 +170,13 @@ None of the previous methods will prevent someone from reading Alice's messages, - . -.NET also provides and . But the MD5 and SHA-1 algorithms have been found to be insecure, and SHA-2 is now recommended instead. SHA-2 includes SHA256, SHA384, and SHA512. +.NET also provides and for standards conformance and backward compatibility with existing data formats and protocols. However, the MD5 and SHA-1 algorithms have been found to be insecure per [NIST SP 800-131A](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final). ## Random Number Generation Random number generation is integral to many cryptographic operations. For example, cryptographic keys need to be as random as possible so that it is infeasible to reproduce them. Cryptographic random number generators must generate output that is computationally infeasible to predict with a probability that is better than one half. Therefore, any method of predicting the next output bit must not perform better than random guessing. The classes in .NET use random number generators to generate cryptographic keys. -The class is an implementation of a random number generator algorithm. +Use the static methods of to obtain cryptographically secure random numbers. ## ClickOnce Manifests diff --git a/docs/standard/security/cryptographic-signatures.md b/docs/standard/security/cryptographic-signatures.md index f04882f7d9584..4bf261246fb9b 100644 --- a/docs/standard/security/cryptographic-signatures.md +++ b/docs/standard/security/cryptographic-signatures.md @@ -47,9 +47,10 @@ Module Program Dim sharedParameters As RSAParameters Dim signedHash As Byte() - ' Generate signature + ' Generate signature with Pkcs1 padding. + ' When creating RSA signatures, choose a padding mode that is appropriate to your needs. Using rsa As RSA = RSA.Create() - sharedParameters = rsa.ExportParameters(True) + sharedParameters = rsa.ExportParameters(False) Dim rsaFormatter As New RSAPKCS1SignatureFormatter(rsa) rsaFormatter.SetHashAlgorithm(NameOf(SHA256)) @@ -67,13 +68,14 @@ using System.Text; using SHA256 alg = SHA256.Create(); -byte[] data = Encoding.ASCII.GetBytes("Hello, from the .NET Docs!"); +byte[] data = Encoding.UTF8.GetBytes("Hello, from the .NET Docs!"); byte[] hash = alg.ComputeHash(data); RSAParameters sharedParameters; byte[] signedHash; -// Generate signature +// Generate signature with Pkcs1 padding. +// When creating RSA signatures, choose a padding mode that is appropriate to your needs. using (RSA rsa = RSA.Create()) { sharedParameters = rsa.ExportParameters(false); diff --git a/docs/standard/security/cryptography-model.md b/docs/standard/security/cryptography-model.md index 69e5bdff94d5a..50c13d963e583 100644 --- a/docs/standard/security/cryptography-model.md +++ b/docs/standard/security/cryptography-model.md @@ -64,7 +64,7 @@ In most cases, you don't need to directly reference an algorithm implementation You can select an algorithm for different reasons: for example, for data integrity, for data privacy, or to generate a key. Symmetric and hash algorithms are intended for protecting data for either integrity reasons (protect from change) or privacy reasons (protect from viewing). Hash algorithms are used primarily for data integrity. -Here is a list of recommended algorithms by application: +Here is a partial list of algorithms by application: - Data privacy: - @@ -83,6 +83,7 @@ Here is a list of recommended algorithms by application: - Generating a key from a password: - + ## See also - [Cryptographic Services](cryptographic-services.md) diff --git a/docs/standard/security/decrypting-data.md b/docs/standard/security/decrypting-data.md index 8097ffb2a87b3..8e6d5ddc6f674 100644 --- a/docs/standard/security/decrypting-data.md +++ b/docs/standard/security/decrypting-data.md @@ -2,6 +2,7 @@ title: "Decrypting data" description: Learn how to decrypt data in .NET, using a symmetric algorithm or an asymmetric algorithm. ms.date: 11/14/2022 +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -19,6 +20,9 @@ Decryption is the reverse operation of encryption. For secret-key encryption, yo ## Symmetric decryption +> [!IMPORTANT] +> Symmetric decryption with CBC mode (the default for `Aes.Create()`) is vulnerable to padding oracle attacks if the ciphertext integrity isn't verified before decryption. Always verify data integrity (for example, by using an HMAC with an Encrypt-then-MAC pattern) before attempting to decrypt. For more information, see [Timing vulnerabilities with CBC-mode symmetric decryption using padding](vulnerabilities-cbc-mode.md). + The decryption of data encrypted with symmetric algorithms is similar to the process used to encrypt data with symmetric algorithms. The class is used with symmetric cryptography classes provided by .NET to decrypt data read from any managed stream object. The following example illustrates how to create a new instance of the default implementation class for the algorithm. The instance is used to perform decryption on a object. This example first creates a new instance of the implementation class. It reads the initialization vector (IV) value from a managed stream variable, `fileStream`. Next it instantiates a object and initializes it to the value of the `fileStream` instance. The method from the instance is passed the IV value and the same key that was used for encryption. @@ -35,12 +39,12 @@ CryptoStream cryptStream = new CryptoStream( fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read); ``` -The following example shows the entire process of creating a stream, decrypting the stream, reading from the stream, and closing the streams. A file stream object is created that reads a file named *TestData.txt*. The file stream is then decrypted using the **CryptoStream** class and the **Aes** class. This example specifies key value that is used in the symmetric encryption example for [Encrypting Data](encrypting-data.md). It does not show the code needed to encrypt and transfer these values. +The following example shows the entire process of creating a stream, decrypting the stream, reading from the stream, and closing the streams. A file stream object is created that reads a file named *TestData.txt*. The file stream is then decrypted using the **CryptoStream** class and the **Aes** class. This example specifies the same key value that is used in the symmetric encryption example for [Encrypting Data](encrypting-data.md). It does not show the code needed to encrypt and transfer these values. :::code language="csharp" source="snippets/decrypting-data/csharp/aes-decrypt.cs"::: :::code language="vb" source="snippets/decrypting-data/vb/aes-decrypt.vb"::: -The preceding example uses the same key, and algorithm used in the symmetric encryption example for [Encrypting Data](encrypting-data.md). It decrypts the *TestData.txt* file that is created by that example and displays the original text on the console. +The preceding example uses the same key and algorithm used in the symmetric encryption example for [Encrypting Data](encrypting-data.md). It decrypts the *TestData.txt* file that is created by that example and displays the original text on the console. ## Asymmetric decryption @@ -51,27 +55,31 @@ For information on how to store an asymmetric key in secure cryptographic key co The following example illustrates the decryption of two arrays of bytes that represent a symmetric key and IV. For information on how to extract the asymmetric public key from the object in a format that you can easily send to a third party, see [Encrypting Data](encrypting-data.md#asymmetric-encryption). ```vb -'Create a new instance of the RSA class. -Dim rsa As RSA = RSA.Create() +'Create a new instance of the RSA class. The 2048-bit key size shown +'here is for illustration; choose a key size that matches your +'security requirements per NIST SP 800-57. +Dim rsa As RSA = RSA.Create(2048) ' Export the public key information and send it to a third party. ' Wait for the third party to encrypt some data and send it back. -'Decrypt the symmetric key and IV. -symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.Pkcs1) -symmetricIV = rsa.Decrypt(encryptedSymmetricIV, RSAEncryptionPadding.Pkcs1) +'Decrypt the symmetric key and IV using OAEP padding. +symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.OaepSHA256) +symmetricIV = rsa.Decrypt(encryptedSymmetricIV, RSAEncryptionPadding.OaepSHA256) ``` ```csharp -//Create a new instance of the RSA class. -RSA rsa = RSA.Create(); +// Create a new instance of the RSA class. The 2048-bit key size shown +// here is for illustration; choose a key size that matches your +// security requirements per NIST SP 800-57. +RSA rsa = RSA.Create(2048); // Export the public key information and send it to a third party. // Wait for the third party to encrypt some data and send it back. -//Decrypt the symmetric key and IV. -symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.Pkcs1); -symmetricIV = rsa.Decrypt(encryptedSymmetricIV , RSAEncryptionPadding.Pkcs1); +// Decrypt the symmetric key and IV using OAEP padding. +symmetricKey = rsa.Decrypt(encryptedSymmetricKey, RSAEncryptionPadding.OaepSHA256); +symmetricIV = rsa.Decrypt(encryptedSymmetricIV, RSAEncryptionPadding.OaepSHA256); ``` ## See also diff --git a/docs/standard/security/encrypting-data.md b/docs/standard/security/encrypting-data.md index ce3f1e37c5b6e..0bc5db86cf05f 100644 --- a/docs/standard/security/encrypting-data.md +++ b/docs/standard/security/encrypting-data.md @@ -2,6 +2,7 @@ title: "Encrypting data" description: Learn how to encrypt data in .NET, using a symmetric algorithm or an asymmetric algorithm. ms.date: 11/14/2022 +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -19,6 +20,9 @@ Symmetric encryption and asymmetric encryption are performed using different pro ## Symmetric encryption +> [!IMPORTANT] +> The `Aes.Create()` method defaults to CBC mode without built-in authentication. CBC mode without integrity verification is vulnerable to padding oracle attacks. For production scenarios, verify data integrity before decryption—for example, by applying an Encrypt-then-MAC pattern. For more information, see [Timing vulnerabilities with CBC-mode symmetric decryption using padding](vulnerabilities-cbc-mode.md). + The managed symmetric cryptography classes are used with a special stream class called a that encrypts data read into the stream. The **CryptoStream** class is initialized with a managed stream class, a class that implements the interface (created from a class that implements a cryptographic algorithm), and a enumeration that describes the type of access permitted to the **CryptoStream**. The **CryptoStream** class can be initialized using any class that derives from the class, including , , and . Using these classes, you can perform symmetric encryption on a variety of stream objects. The following example illustrates how to create a new instance of the default implementation class for the algorithm. The instance is used to perform encryption on a **CryptoStream** class. In this example, the **CryptoStream** is initialized with a stream object called `fileStream` that can be any type of managed stream. The **CreateEncryptor** method from the **Aes** class is passed the key and IV that are used for encryption. In this case, the default key and IV generated from `aes` are used. @@ -60,7 +64,10 @@ The encryption failed. Asymmetric algorithms are usually used to encrypt small amounts of data such as the encryption of a symmetric key and IV. Typically, an individual performing asymmetric encryption uses the public key generated by another party. The class is provided by .NET for this purpose. -The following example uses public key information to encrypt a symmetric key and IV. Two byte arrays are initialized that represents the public key of a third party. An object is initialized to these values. Next, the **RSAParameters** object (along with the public key it represents) is imported into an **RSA** instance using the method. Finally, the private key and IV created by an class are encrypted. This example requires systems to have 128-bit encryption installed. +The following example uses public key information to encrypt a symmetric key and IV. An key pair is generated (the 2048-bit key size shown is for illustration—choose a size that matches your security requirements per [NIST SP 800-57](https://csrc.nist.gov/pubs/sp/800/57/pt1/r5/final)). The public key from one party is used to encrypt the symmetric key and IV generated by an instance, using OAEP padding for security. + +> [!IMPORTANT] +> Use (or higher) instead of . PKCS#1 v1.5 padding is deprecated for new systems per [NIST SP 800-56B](https://csrc.nist.gov/pubs/sp/800/56b/r2/final). Use RSA key sizes of at least 2048 bits per [NIST SP 800-57](https://csrc.nist.gov/pubs/sp/800/57/pt1/r5/final). ```vb Imports System @@ -69,34 +76,17 @@ Imports System.Security.Cryptography Module Module1 Sub Main() - 'Initialize the byte arrays to the public key information. - Dim modulus As Byte() = {214, 46, 220, 83, 160, 73, 40, 39, 201, 155, 19, 202, 3, 11, 191, 178, 56, 74, 90, 36, 248, 103, 18, 144, 170, 163, 145, 87, 54, 61, 34, 220, 222, 207, 137, 149, 173, 14, 92, 120, 206, 222, 158, 28, 40, 24, 30, 16, 175, 108, 128, 35, 230, 118, 40, 121, 113, 125, 216, 130, 11, 24, 90, 48, 194, 240, 105, 44, 76, 34, 57, 249, 228, 125, 80, 38, 9, 136, 29, 117, 207, 139, 168, 181, 85, 137, 126, 10, 126, 242, 120, 247, 121, 8, 100, 12, 201, 171, 38, 226, 193, 180, 190, 117, 177, 87, 143, 242, 213, 11, 44, 180, 113, 93, 106, 99, 179, 68, 175, 211, 164, 116, 64, 148, 226, 254, 172, 147} - - Dim exponent As Byte() = {1, 0, 1} - - 'Create values to store encrypted symmetric keys. - Dim encryptedSymmetricKey() As Byte - Dim encryptedSymmetricIV() As Byte - - 'Create a new instance of the default RSA implementation class. - Dim rsa As RSA = RSA.Create() - - 'Create a new instance of the RSAParameters structure. - Dim rsaKeyInfo As New RSAParameters() - - 'Set rsaKeyInfo to the public key values. - rsaKeyInfo.Modulus = modulus - rsaKeyInfo.Exponent = exponent - - 'Import key parameters into rsa - rsa.ImportParameters(rsaKeyInfo) + 'Create a new RSA key pair. The 2048-bit key size shown here is + 'for illustration; choose a key size that matches your security + 'requirements per NIST SP 800-57. + Dim rsa As RSA = RSA.Create(2048) 'Create a new instance of the default Aes implementation class. Dim aes As Aes = Aes.Create() - 'Encrypt the symmetric key and IV. - encryptedSymmetricKey = rsa.Encrypt(aes.Key, RSAEncryptionPadding.Pkcs1) - encryptedSymmetricIV = rsa.Encrypt(aes.IV, RSAEncryptionPadding.Pkcs1) + 'Encrypt the symmetric key and IV using OAEP padding. + Dim encryptedSymmetricKey As Byte() = rsa.Encrypt(aes.Key, RSAEncryptionPadding.OaepSHA256) + Dim encryptedSymmetricIV As Byte() = rsa.Encrypt(aes.IV, RSAEncryptionPadding.OaepSHA256) End Sub End Module @@ -110,44 +100,17 @@ class Class1 { static void Main() { - //Initialize the byte arrays to the public key information. - byte[] modulus = - { - 214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56, - 74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222, - 207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175, - 108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194, - 240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139, - 168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171, - 38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93, - 106,99,179,68,175,211,164,116,64,148,226,254,172,147 - }; - - byte[] exponent = { 1, 0, 1 }; - - //Create values to store encrypted symmetric keys. - byte[] encryptedSymmetricKey; - byte[] encryptedSymmetricIV; - - //Create a new instance of the RSA class. - RSA rsa = RSA.Create(); - - //Create a new instance of the RSAParameters structure. - RSAParameters rsaKeyInfo = new RSAParameters(); - - //Set rsaKeyInfo to the public key values. - rsaKeyInfo.Modulus = modulus; - rsaKeyInfo.Exponent = exponent; - - //Import key parameters into rsa. - rsa.ImportParameters(rsaKeyInfo); - - //Create a new instance of the default Aes implementation class. + // Create a new RSA key pair. The 2048-bit key size shown here is + // for illustration; choose a key size that matches your security + // requirements per NIST SP 800-57. + RSA rsa = RSA.Create(2048); + + // Create a new instance of the default Aes implementation class. Aes aes = Aes.Create(); - //Encrypt the symmetric key and IV. - encryptedSymmetricKey = rsa.Encrypt(aes.Key, RSAEncryptionPadding.Pkcs1); - encryptedSymmetricIV = rsa.Encrypt(aes.IV, RSAEncryptionPadding.Pkcs1); + // Encrypt the symmetric key and IV using OAEP padding. + byte[] encryptedSymmetricKey = rsa.Encrypt(aes.Key, RSAEncryptionPadding.OaepSHA256); + byte[] encryptedSymmetricIV = rsa.Encrypt(aes.IV, RSAEncryptionPadding.OaepSHA256); } } ``` diff --git a/docs/standard/security/how-to-access-hardware-encryption-devices.md b/docs/standard/security/how-to-access-hardware-encryption-devices.md index f44ae4c55c1ab..fedfddd0591cd 100644 --- a/docs/standard/security/how-to-access-hardware-encryption-devices.md +++ b/docs/standard/security/how-to-access-hardware-encryption-devices.md @@ -2,6 +2,7 @@ description: "Learn more about: How to: Access Hardware Encryption Devices" title: "How to: Access Hardware Encryption Devices" ms.date: 07/14/2020 +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -15,7 +16,7 @@ helpviewer_keywords: # How to: Access hardware encryption devices > [!NOTE] -> This article applies to Windows. +> This article applies to Windows. The and classes are Windows-specific APIs for accessing CAPI-based hardware cryptographic providers such as smart cards. You can use the class to access hardware encryption devices. For example, you can use this class to integrate your application with a smart card, a hardware random number generator, or a hardware implementation of a particular cryptographic algorithm. @@ -35,15 +36,14 @@ The class creates a cryptograp 1. Create a new instance of the class, passing the integer provider type and the provider name to the constructor. -2. Create a new instance of the , passing the object to the constructor. +2. Create a new instance of the , passing the object to the constructor. Note that is obsolete starting in .NET 6 (SYSLIB0023); however, it remains necessary for targeting a specific CAPI-based hardware random number generator. For software-based random number generation, use instead. 3. Create a random value using the or method. ## Example -The following code example demonstrates how to sign data using a smart card. The code example creates a object that exposes a smart card, and then initializes an object using the CSP. The code example then signs and verifies some data. +The following code example demonstrates how to sign data using a smart card. The code example creates a object that exposes a smart card, and then initializes an object using the CSP. The code example then signs and verifies some data. -Due to collision problems with SHA1, we recommend SHA256 or better. [!code-csharp[Cryptography.SmartCardCSP#1](../../../samples/snippets/csharp/VS_Snippets_CLR/Cryptography.SmartCardCSP/CS/example.cs#1)] [!code-vb[Cryptography.SmartCardCSP#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Cryptography.SmartCardCSP/VB/example.vb#1)] diff --git a/docs/standard/security/how-to-encrypt-xml-elements-with-symmetric-keys.md b/docs/standard/security/how-to-encrypt-xml-elements-with-symmetric-keys.md index ab9da75ee4c3b..aa7efb79c3328 100644 --- a/docs/standard/security/how-to-encrypt-xml-elements-with-symmetric-keys.md +++ b/docs/standard/security/how-to-encrypt-xml-elements-with-symmetric-keys.md @@ -2,6 +2,7 @@ description: "Learn more about: How to: Encrypt XML Elements with Symmetric Keys" title: "How to: Encrypt XML Elements with Symmetric Keys" ms.date: 07/14/2020 +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -20,6 +21,9 @@ ms.assetid: d8461a44-aa2c-4ef4-b3e4-ab7cbaaee1b5 You can use the classes in the namespace to encrypt an element within an XML document. XML Encryption allows you to store or transport sensitive XML, without worrying about the data being easily read. This procedure encrypts an XML element using the Advanced Encryption Standard (AES) algorithm. +> [!NOTE] +> The XML Encryption 1.0 standard uses CBC mode by default, which doesn't provide authentication. For scenarios that require strong integrity guarantees, consider using an Encrypt-then-Sign approach. For more information, see [Timing vulnerabilities with CBC-mode symmetric decryption using padding](vulnerabilities-cbc-mode.md). + For information about how to decrypt an XML element that was encrypted using this procedure, see [How to: Decrypt XML Elements with Symmetric Keys](how-to-decrypt-xml-elements-with-symmetric-keys.md). When you use a symmetric algorithm like AES to encrypt XML data, you must use the same key to encrypt and decrypt the XML data. The example in this procedure assumes that the encrypted XML will be decrypted using the same key, and that the encrypting and decrypting parties agree on the algorithm and key to use. This example does not store or encrypt the AES key within the encrypted XML. diff --git a/docs/standard/security/snippets/cryptographic-signatures/csharp/Program.cs b/docs/standard/security/snippets/cryptographic-signatures/csharp/Program.cs index 1cb8ec594af59..683084f519613 100644 --- a/docs/standard/security/snippets/cryptographic-signatures/csharp/Program.cs +++ b/docs/standard/security/snippets/cryptographic-signatures/csharp/Program.cs @@ -3,13 +3,14 @@ using SHA256 alg = SHA256.Create(); -byte[] data = Encoding.ASCII.GetBytes("Hello, from the .NET Docs!"); +byte[] data = Encoding.UTF8.GetBytes("Hello, from the .NET Docs!"); byte[] hash = alg.ComputeHash(data); RSAParameters sharedParameters; byte[] signedHash; -// Generate signature +// Generate signature with Pkcs1 padding. +// When creating RSA signatures, choose a padding mode that is appropriate to your needs. using (RSA rsa = RSA.Create()) { sharedParameters = rsa.ExportParameters(false); @@ -20,7 +21,9 @@ signedHash = rsaFormatter.CreateSignature(hash); } -// Verify signature +// Verify signature. +// Since the signature was generated with Pkcs1 padding, +// it can only be verified with Pkcs1 padding. using (RSA rsa = RSA.Create()) { rsa.ImportParameters(sharedParameters); diff --git a/docs/standard/security/snippets/cryptographic-signatures/vb/Program.vb b/docs/standard/security/snippets/cryptographic-signatures/vb/Program.vb index 717b393e287c6..072975a151113 100644 --- a/docs/standard/security/snippets/cryptographic-signatures/vb/Program.vb +++ b/docs/standard/security/snippets/cryptographic-signatures/vb/Program.vb @@ -12,16 +12,19 @@ Module Program Dim sharedParameters As RSAParameters Dim signedHash As Byte() - ' Generate signature + ' Generate signature with Pkcs1 padding. + ' When creating RSA signatures, choose a padding mode that is appropriate to your needs. Using rsa As RSA = RSA.Create() - sharedParameters = rsa.ExportParameters(True) + sharedParameters = rsa.ExportParameters(False) Dim rsaFormatter As New RSAPKCS1SignatureFormatter(rsa) rsaFormatter.SetHashAlgorithm(NameOf(SHA256)) signedHash = rsaFormatter.CreateSignature(hash) End Using - ' Verify signature + ' Verify signature. + ' Since the signature was generated with Pkcs1 padding, + ' it can only be verified with Pkcs1 padding. Using rsa As RSA = RSA.Create() rsa.ImportParameters(sharedParameters) diff --git a/docs/standard/security/snippets/decrypting-data/csharp/aes-decrypt.cs b/docs/standard/security/snippets/decrypting-data/csharp/aes-decrypt.cs index 3223c39267d73..cc3240451c3ac 100644 --- a/docs/standard/security/snippets/decrypting-data/csharp/aes-decrypt.cs +++ b/docs/standard/security/snippets/decrypting-data/csharp/aes-decrypt.cs @@ -18,6 +18,9 @@ numBytesToRead -= n; } + // This key is for illustration purposes only and must + // match the key used during encryption. + // In production, use a securely stored or managed key. byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, diff --git a/docs/standard/security/snippets/decrypting-data/vb/aes-decrypt.vb b/docs/standard/security/snippets/decrypting-data/vb/aes-decrypt.vb index 1634e13334237..a5c633f7ee676 100644 --- a/docs/standard/security/snippets/decrypting-data/vb/aes-decrypt.vb +++ b/docs/standard/security/snippets/decrypting-data/vb/aes-decrypt.vb @@ -4,8 +4,9 @@ Imports System.Security.Cryptography Module Module1 Sub Main() - ' Decryption key must be the same value that was used - ' to encrypt the stream. + ' This key is for illustration purposes only and must + ' match the key used during encryption. + ' In production, use a securely stored or managed key. Dim key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16} Try diff --git a/docs/standard/security/snippets/encrypting-data/csharp/aes-encrypt.cs b/docs/standard/security/snippets/encrypting-data/csharp/aes-encrypt.cs index 66e3199dec9d5..ee21c127a022c 100644 --- a/docs/standard/security/snippets/encrypting-data/csharp/aes-encrypt.cs +++ b/docs/standard/security/snippets/encrypting-data/csharp/aes-encrypt.cs @@ -6,6 +6,8 @@ { using (Aes aes = Aes.Create()) { + // This key is for illustration purposes only. + // In production, use a securely stored or managed key. byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, diff --git a/docs/standard/security/snippets/encrypting-data/vb/aes-encrypt.vb b/docs/standard/security/snippets/encrypting-data/vb/aes-encrypt.vb index 50ab081abdba7..0783b144d3525 100644 --- a/docs/standard/security/snippets/encrypting-data/vb/aes-encrypt.vb +++ b/docs/standard/security/snippets/encrypting-data/vb/aes-encrypt.vb @@ -11,8 +11,8 @@ Module Module1 ' Create a new instance of the default Aes implementation class ' and configure encryption key. Using aes As Aes = Aes.Create() - 'Encryption key used to encrypt the stream. - 'The same value must be used to encrypt and decrypt the stream. + ' This key is for illustration purposes only. + ' In production, use a securely stored or managed key. Dim key As Byte() = { &H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16 @@ -41,11 +41,8 @@ Module Module1 End Using End Using - 'Inform the user that the message was written - 'to the stream. - Console.WriteLine("The text was encrypted.") + Console.WriteLine("The file was encrypted.") Catch - 'Inform the user that an exception was raised. Console.WriteLine("The encryption failed.") Throw End Try diff --git a/docs/standard/security/vulnerabilities-cbc-mode.md b/docs/standard/security/vulnerabilities-cbc-mode.md index 4281cf6267773..86dcc878ea602 100644 --- a/docs/standard/security/vulnerabilities-cbc-mode.md +++ b/docs/standard/security/vulnerabilities-cbc-mode.md @@ -70,7 +70,7 @@ First and foremost, Microsoft recommends that any data that has confidentiality Next, analyze your application to: - Understand precisely what encryption you're performing and what encryption is being provided by the platforms and APIs you're using. -- Be certain that each usage at each layer of a symmetric [block cipher algorithm](https://en.wikipedia.org/wiki/Block_cipher#Notable_block_ciphers), such as AES and 3DES, in CBC mode incorporate the use of a secret-keyed data integrity check (an asymmetric signature, an HMAC, or to change the cipher mode to an [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption) (AE) mode such as GCM or CCM). +- Be certain that each usage at each layer of a symmetric [block cipher algorithm](https://en.wikipedia.org/wiki/Block_cipher#Notable_block_ciphers), such as AES and 3DES, in CBC mode incorporate the use of a secret-keyed data integrity check, such as an asymmetric signature, an HMAC, or another authenticated-encryption design that provides integrity protection. Based on the current research, it's generally believed that when the authentication and encryption steps are performed independently for non-AE modes of encryption, authenticating the ciphertext (encrypt-then-sign) is the best general option. However, there's no one-size-fits-all correct answer to cryptography and this generalization isn't as good as directed advice from a professional cryptographer. diff --git a/docs/visual-basic/programming-guide/language-features/strings/walkthrough-encrypting-and-decrypting-strings.md b/docs/visual-basic/programming-guide/language-features/strings/walkthrough-encrypting-and-decrypting-strings.md index ff39a40dfee8b..2e42cdff7cb54 100644 --- a/docs/visual-basic/programming-guide/language-features/strings/walkthrough-encrypting-and-decrypting-strings.md +++ b/docs/visual-basic/programming-guide/language-features/strings/walkthrough-encrypting-and-decrypting-strings.md @@ -2,7 +2,8 @@ description: "Learn more about: Walkthrough: Encrypting and Decrypting Strings in Visual Basic" title: "Encrypting and Decrypting Strings" ms.date: 07/20/2015 -helpviewer_keywords: +ai-usage: ai-assisted +helpviewer_keywords: - "encryption [Visual Basic], strings" - "strings [Visual Basic], encrypting" - "decryption [Visual Basic], strings" @@ -11,6 +12,9 @@ ms.assetid: 1f51e40a-2f88-43e2-a83e-28a0b5c0d6fd --- # Walkthrough: Encrypting and Decrypting Strings in Visual Basic +> [!WARNING] +> The TripleDES (3DES) algorithm demonstrated in this walkthrough is deprecated per [NIST SP 800-131A](https://csrc.nist.gov/pubs/sp/800/131a/r2/final) and should not be used for new development. Use instead. For current guidance, see [.NET cryptography model](../../../../standard/security/cryptography-model.md). + This walkthrough shows you how to use the class to encrypt and decrypt strings using the Triple Data Encryption Standard (3DES) algorithm. The first step is to create a simple wrapper class that encapsulates the 3DES algorithm and stores the encrypted data as a base-64 encoded string. Then, that wrapper is used to securely store private user data in a publicly accessible text file. You can use encryption to protect user secrets (for example, passwords) and to make credentials unreadable by unauthorized users. This can protect an authorized user's identity from being stolen, which protects the user's assets and provides non-repudiation. Encryption can also protect a user's data from being accessed by unauthorized users. @@ -18,7 +22,7 @@ This walkthrough shows you how to use the [!IMPORTANT] -> The Rijndael (now referred to as Advanced Encryption Standard [AES]) and Triple Data Encryption Standard (3DES) algorithms provide greater security than DES because they are more computationally intensive. For more information, see and . +> The Triple Data Encryption Standard (3DES) and DES algorithms are deprecated. Use the Advanced Encryption Standard (AES) for new encryption scenarios. For more information, see . ### To create the encryption wrapper diff --git a/samples/snippets/csharp/VS_Snippets_CLR/CryptoWalkThru/cs/Form1.cs b/samples/snippets/csharp/VS_Snippets_CLR/CryptoWalkThru/cs/Form1.cs index ac287caa88f3c..c3912db973b3b 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/CryptoWalkThru/cs/Form1.cs +++ b/samples/snippets/csharp/VS_Snippets_CLR/CryptoWalkThru/cs/Form1.cs @@ -35,6 +35,22 @@ public partial class Form1 : Form private void Close_Click(object sender, EventArgs e) => Application.Exit(); + private static void ReadBytesExactly(Stream stream, byte[] buffer, int offset, int count) + { + while (count > 0) + { + int bytesRead = stream.Read(buffer, offset, count); + + if (bytesRead == 0) + { + throw new EndOfStreamException("Could not read the expected number of bytes from the stream."); + } + + offset += bytesRead; + count -= bytesRead; + } + } + #endregion #region Snippet2 - buttonCreateAsmKeys @@ -205,10 +221,8 @@ private void DecryptFile(FileInfo file) // file (inFs) and save the decrypted file (outFs). using (var inFs = new FileStream(file.FullName, FileMode.Open)) { - inFs.Seek(0, SeekOrigin.Begin); - inFs.Read(LenK, 0, 3); - inFs.Seek(4, SeekOrigin.Begin); - inFs.Read(LenIV, 0, 3); + ReadBytesExactly(inFs, LenK, 0, LenK.Length); + ReadBytesExactly(inFs, LenIV, 0, LenIV.Length); // Convert the lengths to integer values. int lenK = BitConverter.ToInt32(LenK, 0); @@ -230,9 +244,9 @@ private void DecryptFile(FileInfo file) // starting from index 8 // after the length values. inFs.Seek(8, SeekOrigin.Begin); - inFs.Read(KeyEncrypted, 0, lenK); + ReadBytesExactly(inFs, KeyEncrypted, 0, lenK); inFs.Seek(8 + lenK, SeekOrigin.Begin); - inFs.Read(IV, 0, lenIV); + ReadBytesExactly(inFs, IV, 0, lenIV); Directory.CreateDirectory(DecrFolder); // diff --git a/samples/snippets/csharp/VS_Snippets_CLR/Cryptography.SmartCardCSP/CS/example.cs b/samples/snippets/csharp/VS_Snippets_CLR/Cryptography.SmartCardCSP/CS/example.cs index d51e3b9cc93c6..7263d406cbd25 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/Cryptography.SmartCardCSP/CS/example.cs +++ b/samples/snippets/csharp/VS_Snippets_CLR/Cryptography.SmartCardCSP/CS/example.cs @@ -24,7 +24,7 @@ static void Main(string[] args) // Initialize an RSACryptoServiceProvider object using // the CspParameters object. - RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp); + using RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp); // Create some data to sign. byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; @@ -32,12 +32,12 @@ static void Main(string[] args) Console.WriteLine("Data : " + BitConverter.ToString(data)); // Sign the data using the Smart Card CryptoGraphic Provider. - byte[] sig = rsa.SignData(data, "SHA1"); + byte[] sig = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); Console.WriteLine("Signature : " + BitConverter.ToString(sig)); // Verify the data using the Smart Card CryptoGraphic Provider. - bool verified = rsa.VerifyData(data, "SHA1", sig); + bool verified = rsa.VerifyData(data, sig, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); Console.WriteLine("Verified : " + verified); } diff --git a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs b/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs index 335f0103d116a..b10e806e7f5d1 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs +++ b/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs @@ -19,21 +19,21 @@ public static void Run() /////////////////////////////// // Create the original data to be encrypted (The data length should be a multiple of 16). - byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16"); + byte[] toEncrypt = Encoding.ASCII.GetBytes("ThisIsSomeData16"); - Console.WriteLine($"Original data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Original data: {Encoding.ASCII.GetString(toEncrypt)}"); Console.WriteLine("Encrypting..."); // Encrypt the data in memory. EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon); - Console.WriteLine($"Encrypted data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Encrypted data: {Encoding.ASCII.GetString(toEncrypt)}"); Console.WriteLine("Decrypting..."); // Decrypt the data in memory. DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon); - Console.WriteLine($"Decrypted data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(toEncrypt)}"); /////////////////////////////// // @@ -42,7 +42,7 @@ public static void Run() /////////////////////////////// // Create the original data to be encrypted - toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length."); + toEncrypt = Encoding.ASCII.GetBytes("This is some data of any length."); // Create a file. FileStream fStream = new FileStream("Data.dat", FileMode.OpenOrCreate); @@ -51,7 +51,7 @@ public static void Run() byte[] entropy = CreateRandomEntropy(); Console.WriteLine(); - Console.WriteLine($"Original data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Original data: {Encoding.ASCII.GetString(toEncrypt)}"); Console.WriteLine("Encrypting and writing to disk..."); // Encrypt a copy of the data to the stream. @@ -69,7 +69,7 @@ public static void Run() fStream.Close(); - Console.WriteLine($"Decrypted data: {UnicodeEncoding.ASCII.GetString(decryptData)}"); + Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(decryptData)}"); } catch (Exception e) { @@ -104,9 +104,11 @@ public static byte[] CreateRandomEntropy() // Create a byte array to hold the random value. byte[] entropy = new byte[16]; - // Create a new instance of the RNGCryptoServiceProvider. // Fill the array with a random value. - new RNGCryptoServiceProvider().GetBytes(entropy); + using (var rng = new RNGCryptoServiceProvider()) + { + rng.GetBytes(entropy); + } // Return the array. return entropy; @@ -159,7 +161,19 @@ public static byte[] DecryptDataFromStream(byte[] Entropy, DataProtectionScope S // Read the encrypted data from a stream. if (S.CanRead) { - S.Read(inBuffer, 0, Length); + int offset = 0; + + while (offset < Length) + { + int bytesRead = S.Read(inBuffer, offset, Length - offset); + + if (bytesRead == 0) + { + throw new EndOfStreamException("Could not read the expected number of bytes from the stream."); + } + + offset += bytesRead; + } outBuffer = ProtectedData.Unprotect(inBuffer, Entropy, Scope); } diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/Cryptography.SmartCardCSP/VB/example.vb b/samples/snippets/visualbasic/VS_Snippets_CLR/Cryptography.SmartCardCSP/VB/example.vb index e006c90f905c1..b1c570be8bfa4 100644 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/Cryptography.SmartCardCSP/VB/example.vb +++ b/samples/snippets/visualbasic/VS_Snippets_CLR/Cryptography.SmartCardCSP/VB/example.vb @@ -1,8 +1,6 @@ ' Imports System.Security.Cryptography - - Module SCSign Sub Main(ByVal args() As String) @@ -20,23 +18,23 @@ Module SCSign ' Initialize an RSACryptoServiceProvider object using ' the CspParameters object. - Dim rsa As New RSACryptoServiceProvider(csp) - - ' Create some data to sign. - Dim data() As Byte = {0, 1, 2, 3, 4, 5, 6, 7} + Using rsa As New RSACryptoServiceProvider(csp) + ' Create some data to sign. + Dim data() As Byte = {0, 1, 2, 3, 4, 5, 6, 7} - Console.WriteLine("Data : " + BitConverter.ToString(data)) + Console.WriteLine("Data : " + BitConverter.ToString(data)) - ' Sign the data using the Smart Card CryptoGraphic Provider. - Dim sig As Byte() = rsa.SignData(data, "SHA1") + ' Sign the data using the Smart Card CryptoGraphic Provider. + Dim sig As Byte() = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1) - Console.WriteLine("Signature : " + BitConverter.ToString(sig)) + Console.WriteLine("Signature : " + BitConverter.ToString(sig)) - ' Verify the data using the Smart Card CryptoGraphic Provider. - Dim verified As Boolean = rsa.VerifyData(data, "SHA1", sig) + ' Verify the data using the Smart Card CryptoGraphic Provider. + Dim verified As Boolean = rsa.VerifyData(data, sig, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1) - Console.WriteLine("Verified") + Console.WriteLine("Verified : " + verified.ToString()) + End Using End Sub diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb b/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb index 1b2ea95b3e31c..ac168dd12d57f 100644 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb +++ b/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb @@ -22,21 +22,21 @@ Public Module MemoryProtectionSample ' '''''''''''''''''''''''''''''''''''' ' Create the original data to be encrypted (The data length should be a multiple of 16). - Dim toEncrypt As Byte() = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16") + Dim toEncrypt As Byte() = Encoding.ASCII.GetBytes("ThisIsSomeData16") - Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Original data: " + Encoding.ASCII.GetString(toEncrypt)) Console.WriteLine("Encrypting...") ' Encrypt the data in memory. EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon) - Console.WriteLine("Encrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Encrypted data: " + Encoding.ASCII.GetString(toEncrypt)) Console.WriteLine("Decrypting...") ' Decrypt the data in memory. DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon) - Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Decrypted data: " + Encoding.ASCII.GetString(toEncrypt)) '''''''''''''''''''''''''''''''''''' @@ -45,7 +45,7 @@ Public Module MemoryProtectionSample ' '''''''''''''''''''''''''''''''''''' ' Create the original data to be encrypted - toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length.") + toEncrypt = Encoding.ASCII.GetBytes("This is some data of any length.") ' Create a file. Dim fStream As New FileStream("Data.dat", FileMode.OpenOrCreate) @@ -54,7 +54,7 @@ Public Module MemoryProtectionSample Dim entropy As Byte() = CreateRandomEntropy() Console.WriteLine() - Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Original data: " + Encoding.ASCII.GetString(toEncrypt)) Console.WriteLine("Encrypting and writing to disk...") ' Encrypt a copy of the data to the stream. @@ -72,7 +72,7 @@ Public Module MemoryProtectionSample fStream.Close() - Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(decryptData)) + Console.WriteLine("Decrypted data: " + Encoding.ASCII.GetString(decryptData)) Catch e As Exception @@ -88,7 +88,7 @@ Public Module MemoryProtectionSample Throw New ArgumentNullException("Buffer") End If If Buffer.Length <= 0 Then - Throw New ArgumentException("Buffer") + Throw New ArgumentException("The buffer length was 0.", NameOf(Buffer)) End If ' Encrypt the data in memory. The result is stored in the same array as the original data. @@ -102,7 +102,7 @@ Public Module MemoryProtectionSample Throw New ArgumentNullException("Buffer") End If If Buffer.Length <= 0 Then - Throw New ArgumentException("Buffer") + Throw New ArgumentException("The buffer length was 0.", NameOf(Buffer)) End If ' Decrypt the data in memory. The result is stored in the same array as the original data. @@ -115,11 +115,10 @@ Public Module MemoryProtectionSample ' Create a byte array to hold the random value. Dim entropy(15) As Byte - ' Create a new instance of the RNGCryptoServiceProvider. ' Fill the array with a random value. - Dim RNG As New RNGCryptoServiceProvider() - - RNG.GetBytes(entropy) + Using rng As New RNGCryptoServiceProvider() + rng.GetBytes(entropy) + End Using ' Return the array. Return entropy @@ -133,13 +132,13 @@ Public Module MemoryProtectionSample Throw New ArgumentNullException("Buffer") End If If Buffer.Length <= 0 Then - Throw New ArgumentException("Buffer") + Throw New ArgumentException("The buffer length was 0.", NameOf(Buffer)) End If If Entropy Is Nothing Then Throw New ArgumentNullException("Entropy") End If If Entropy.Length <= 0 Then - Throw New ArgumentException("Entropy") + Throw New ArgumentException("The entropy length was 0.", NameOf(Entropy)) End If If S Is Nothing Then Throw New ArgumentNullException("S") @@ -167,13 +166,13 @@ Public Module MemoryProtectionSample Throw New ArgumentNullException("S") End If If Length <= 0 Then - Throw New ArgumentException("Length") + Throw New ArgumentException("The given length was 0.", NameOf(Length)) End If If Entropy Is Nothing Then Throw New ArgumentNullException("Entropy") End If If Entropy.Length <= 0 Then - Throw New ArgumentException("Entropy") + Throw New ArgumentException("The entropy length was 0.", NameOf(Entropy)) End If @@ -182,7 +181,17 @@ Public Module MemoryProtectionSample ' Read the encrypted data from a stream. If S.CanRead Then - S.Read(inBuffer, 0, Length) + Dim offset As Integer = 0 + + While offset < Length + Dim bytesRead As Integer = S.Read(inBuffer, offset, Length - offset) + + If bytesRead = 0 Then + Throw New EndOfStreamException("Could not read the expected number of bytes from the stream.") + End If + + offset += bytesRead + End While outBuffer = ProtectedData.Unprotect(inBuffer, Entropy, Scope) Else diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vbproj b/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vbproj new file mode 100644 index 0000000000000..202fb09d05106 --- /dev/null +++ b/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vbproj @@ -0,0 +1,13 @@ + + + + Exe + net461 + DPAPI_HowTO + + + + + + +