Skip to content

Latest commit

 

History

History
380 lines (220 loc) · 26.8 KB

README-English.md

File metadata and controls

380 lines (220 loc) · 26.8 KB

📖RSA-csharp Usage Documentation

This document is translated from Chinese to English using Google Translate.

Functions of this project: support PEM (PKCS#1, PKCS#8) format RSA key generation, import, and export in .NET Core and .NET Framework environments; a variety of common RSA encryption signatures padding algorithm support.

  • Support .NET Framework 4.5+, .NET Standard 2.0+ (.NET Core 2.0+, .NET 5+)
  • RSA can be created through PEM, XML format keys
  • RSA can be created by specifying key digits and key parameters
  • Can export PEM, XML format public key, private key; format mutual conversion
  • Public key encryption, private key decryption: NoPadding, PKCS1Padding, OAEP+MD5, OAEP+SHA1 ... SHA3-512
  • Private key signature, public key verification: PKCS1+SHA1 ... SHA3-512, PKCS1+MD5, PSS+SHA1 ... SHA3-512
  • Unconventional: private key encryption, public key decryption, public key signature, private key verification
  • Multilingual support: provide Chinese and English language support
  • There is also a Java version RSA-java, all encrypted signature algorithms are interoperable in Java, .NET, OpenSSL
  • The source code is simple, and compile and test .bat|.sh scripts are provided. The source code can be modified and run without Visual Studio, and can be used by copying

You can just copy the RSA_PEM.cs and RSA_Util.cs files to your project to use all the functions. You can also clone the entire project code and double-click Test-Build-Run.bat to run the test directly (macOS, linux use the terminal to run .sh), through the scripts/Create-dll.bat(sh) script can generate dll files for project reference.

The underlying implementation of the RSA_PEM class uses bytecode parsing of the PEM file at the binary level, which is simple, lightweight, and zero-dependent; RSA_Util is an encapsulation of the RSA operation class, which supports cross-platform use, and can optionally be used with the BouncyCastle encryption enhancement library Richer support for cryptographic signature modes is available.

Source Files Platform Support Instructions Dependencies
RSA_PEM.cs .NET Core, .NET Framework Used to parse and export PEM, create RSA instance NONE
RSA_Util.cs .NET Core, .NET Framework RSA operation class, which encapsulates encryption, decryption, and signature verification RSA_PEM
Program.cs .NET Core, .NET Framework Test console program RSA_PEM, RSA_Util

Screenshot of Test-Build-Run.bat test compilation and operation:

console test

Quick Start: Encryption, Decryption, Signature, Verification

Step 1: Reference RSA-csharp

  • Method 1: Copy the RSA_PEM.cs and RSA_Util.cs files directly to your project and use them.
  • Method 2: Use the scripts/Create-dll.bat(sh) script to generate a dll file, and add the reference of this dll to the project to use it.
  • Method 3: Download the corresponding version of the dll file in Releases (that is, the dll generated by the method 2 script), and add the reference of this dll to the project to use it.

Note: The .NET Framework project may needs to manually reference the System.Numerics assembly to support BigInteger. The project created by vs by default does not automatically import this assembly, and the .NET Core project does not need this operation.

Step 2: Write the code

//Parse pem or xml first, and both public and private keys can be parsed 
//var pem=RSA_PEM.FromPEM("-----BEGIN XXX KEY-----....-----END XXX KEY-----");
//var pem=RSA_PEM.FromXML("<RSAKeyValue><Modulus>....</RSAKeyValue>");

//Directly create RSA operation classes, which can be created as global objects, and both encryption and decryption signatures support concurrent calls
//var rsa=new RSA_Util(pem);
var rsa=new RSA_Util(2048); //You can also directly generate a new key, rsa.ToPEM() gets the pem object

//Optionally register the BouncyCastle encryption enhancement library (just register once when the program starts), which is used to implement the encryption signature padding mode not supported by .NET, NuGet: Portable.BouncyCastle or BouncyCastle.Cryptography
//RSA_Util.UseBouncyCastle(typeof(RsaEngine).Assembly);

//Encrypt with public key, padding mode: PKCS1, you can use OAEP+SHA256 and other padding modes
var enTxt=rsa.Encrypt("PKCS1", "test123");
//Decrypt with private key
var deTxt=rsa.Decrypt("PKCS1", enTxt);

//Sign with private key, padding mode: PKCS1+SHA1, PSS+SHA256 and other padding modes can be used
var sign=rsa.Sign("PKCS1+SHA1", "test123");
//Verify with public key
var isVerify=rsa.Verify("PKCS1+SHA1", sign, "test123");

//Export PEM text
var pemTxt=rsa.ToPEM().ToPEM_PKCS8();

//Unconventional (unsafe, not recommended): private key encryption, public key decryption, public key signature, private key verification
RSA_Util rsaS_Private=rsa.SwapKey_Exponent_D__Unsafe();
RSA_Util rsaS_Public=new RSA_Util(rsa.ToPEM(true)).SwapKey_Exponent_D__Unsafe();
//... rsaS_Private.Encrypt rsaS_Public.Decrypt
//... rsaS_Public.Sign rsaS_Private.Verify

Console.WriteLine(pemTxt+"\n"+enTxt+"\n"+deTxt+"\n"+sign+"\n"+isVerify);
Console.ReadLine();
//****For more examples, please read Program.cs****
//****For more functional methods, please read the detailed documentation below****

If you need function customization, website, app, small program development, etc., please add the QQ group below and contact the group owner (ie the author), thank you~

[QQ group] communication and support

Welcome to join QQ group: 421882406, pure lowercase password: xiangyuecn

📖Documentation

Encryption Paddings

In the table below, Frame is the support of .NET Framework, Core is the support of .NET Core, and BC is the support of the BouncyCastle encryption enhancement library (can be registered through the RSA_Util.UseBouncyCastle method); √ means support, × means no support, and other values are A certain version starts to support; among them, the mask generation function MGF1 of OAEP uses the same Hash algorithm as OAEP.

Padding Algorithm Frame Core BC
NO RSA/ECB/NoPadding
PKCS1 RSA/ECB/PKCS1Padding
OAEP+SHA1 RSA/ECB/OAEPwithSHA-1andMGF1Padding
OAEP+SHA256 RSA/ECB/OAEPwithSHA-256andMGF1Padding 4.6+
OAEP+SHA224 RSA/ECB/OAEPwithSHA-224andMGF1Padding × ×
OAEP+SHA384 RSA/ECB/OAEPwithSHA-384andMGF1Padding 4.6+
OAEP+SHA512 RSA/ECB/OAEPwithSHA-512andMGF1Padding 4.6+
OAEP+SHA-512/224 RSA/ECB/OAEPwithSHA-512/224andMGF1Padding × ×
OAEP+SHA-512/256 RSA/ECB/OAEPwithSHA-512/256andMGF1Padding × ×
OAEP+SHA3-256 RSA/ECB/OAEPwithSHA3-256andMGF1Padding × 8+
OAEP+SHA3-224 RSA/ECB/OAEPwithSHA3-224andMGF1Padding × ×
OAEP+SHA3-384 RSA/ECB/OAEPwithSHA3-384andMGF1Padding × 8+
OAEP+SHA3-512 RSA/ECB/OAEPwithSHA3-512andMGF1Padding × 8+
OAEP+MD5 RSA/ECB/OAEPwithMD5andMGF1Padding 4.6+

Signature Paddings

In the table below, Frame is the support of .NET Framework, Core is the support of .NET Core, and BC is the support of the BouncyCastle encryption enhancement library (can be registered through the RSA_Util.UseBouncyCastle method); √ means support, × means no support, and other values are A certain version starts to support; the number of salt bytes of PSS is equal to the number of bytes of the hash algorithm used, the mask generation function MGF1 of PSS uses the same hash algorithm as that of PSS, and the value of the trailing attribute TrailerField is fixed at 0xBC.

Padding Algorithm Frame Core BC
SHA1 ... SHA3-512 Same as PKCS1+SHA***
PKCS1+SHA1 SHA1withRSA
PKCS1+SHA256 SHA256withRSA
PKCS1+SHA224 SHA224withRSA × ×
PKCS1+SHA384 SHA384withRSA
PKCS1+SHA512 SHA512withRSA
PKCS1+SHA-512/224 SHA512/224withRSA × ×
PKCS1+SHA-512/256 SHA512/256withRSA × ×
PKCS1+SHA3-256 SHA3-256withRSA × 8+
PKCS1+SHA3-224 SHA3-224withRSA × ×
PKCS1+SHA3-384 SHA3-384withRSA × 8+
PKCS1+SHA3-512 SHA3-512withRSA × 8+
PKCS1+MD5 MD5withRSA
PSS+SHA1 SHA1withRSA/PSS 4.6+
PSS+SHA256 SHA256withRSA/PSS 4.6+
PSS+SHA224 SHA224withRSA/PSS × ×
PSS+SHA384 SHA384withRSA/PSS 4.6+
PSS+SHA512 SHA512withRSA/PSS 4.6+
PSS+SHA-512/224 SHA512/224withRSA/PSS × ×
PSS+SHA-512/256 SHA512/256withRSA/PSS × ×
PSS+SHA3-256 SHA3-256withRSA/PSS × 8+
PSS+SHA3-224 SHA3-224withRSA/PSS × ×
PSS+SHA3-384 SHA3-384withRSA/PSS × 8+
PSS+SHA3-512 SHA3-512withRSA/PSS × 8+
PSS+MD5 MD5withRSA/PSS 4.6+

RSA_PEM Class Documentation

The RSA_PEM.cs file does not depend on any files, you can directly copy this file to use in your project; through FromPEM, ToPEM and FromXML, ToXML two pairs of methods, you can implement PEM PKCS#1, PKCS#8 mutual conversion, PEM, XML mutual conversion.

Note: openssl rsa -in privateKey -pubout exports PKCS#8 format public key (used more), openssl rsa -pubin -in PKCS#8 publicKey -RSAPublicKey_out exports PKCS#1 format public key (rarely used).

Static Attributes and Methods

RSA_PEM FromPEM(string pem): Create RSA with PEM format key, support PKCS#1, PKCS#8 format PEM, error will throw an exception. pem format such as: -----BEGIN XXX KEY-----....-----END XXX KEY-----.

RSA_PEM FromXML(string xml): Convert the key in XML format to PEM, support public key xml, private key xml, and an exception will be thrown if an error occurs. xml format such as: <RSAKeyValue><Modulus>....</RSAKeyValue>.

string T(string zh, string en): Simplified multi-language support, returns Chinese or English according to the current language Lang value.

string Lang: Simplified multi-language support, value: zh (Simplified Chinese), en (English-US), the default value is based on the system, and the specified language can be assigned.

Construction Methods

RSA_PEM(RSA rsa, bool convertToPublic = false): Construct a PEM through the public key or private key in RSA. If convertToPublic, the RSA containing the private key will only read the public key, and the RSA containing only the public key will not be affected.

RSA_PEM(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ): Construct a PEM through the full amount of PEM field parameters. Except for the modulus and public key exponent that must be provided, other private key exponent information must be provided or not provided at all (the exported PEM only contains the public key) Note: all If the first byte of the parameter is 0, it must be removed first.

RSA_PEM(byte[] modulus, byte[] exponent, byte[] dOrNull): Construct a PEM through the public key exponent and the private key exponent, and P and Q will be calculated in reverse, but they are extremely unlikely to be the same as the P and Q of the original generated key. Note: If the first byte of all parameters is 0, it must be removed first. Errors will throw exceptions. The private key exponent may not be provided, and the exported PEM only contains the public key.

Instance Attributes

byte[]: Key_Modulus(Modulus n, both public key and private key), Key_Exponent(Public key exponent e, both public key and private key), Key_D(Private key exponent d, only available when private key); These 3 are enough for encryption and decryption.

byte[]: Val_P(prime1), Val_Q(prime2), Val_DP(exponent1), Val_DQ(exponent2), Val_InverseQ(coefficient); The private key in PEM has more values; these values can be deduced through n, e, and d (only the effective value is deduced, which is different from the original value with high probability).

int KeySize: Key digits.

bool HasPrivate: Whether to include the private key.

Instance Methods

RSA GetRSA_ForCore(): Convert the public key or private key in PEM into an RSA object. If the private key is not provided, RSA only contains the public key. The returned RSA supports cross-platform use, but only supports use in the .NET Core environment.

RSACryptoServiceProvider GetRSA_ForWindows(): Convert the public key or private key in PEM into an RSA object. If the private key is not provided, RSA only contains the public key. Both .NET Core and .NET Framework are available, but the returned RSACryptoServiceProvider does not support cross-platform, so it can only be used in Windows systems.

void GetRSA__ImportParameters(RSA rsa): Import the key parameter into the RSA object, this method is called in GetRSA_ForCore, GetRSA_ForWindows, and can be used to create other types of RSA.

RSA_PEM CopyToNew(bool convertToPublic = false): Copy the key in the current PEM to a new PEM object. convertToPublic: When equal to true, the PEM containing the private key will only return the public key, and the PEM containing only the public key will not be affected.

RSA_PEM SwapKey_Exponent_D__Unsafe(): [Unsafe and not recommended] Swap the public key exponent (Key_Exponent) and the private key exponent (Key_D): use the public key as the private key (new.Key_D=this.Key_Exponent) and the private key as the public key (new.Key_Exponent=this.Key_D), returns a new PEM object; for example, used for: private key encryption, public key decryption, this is an unconventional usage. The current object must contain a private key, otherwise an exception will be thrown if it cannot be swapped. Note: It is very insecure to use the public key as a private key, because the public key exponent of most generated keys is 0x10001 (AQAB), which is too easy to guess and cannot be used as a real private key.

byte[] ToDER(bool convertToPublic, bool privateUsePKCS8, bool publicUsePKCS8): Convert the key pair in RSA to DER format. The DER format is binary data before Base64 text encoding in PEM. Refer to the ToPEM method for parameter meanings.

string ToPEM(bool convertToPublic, bool privateUsePKCS8, bool publicUsePKCS8): Convert the key in RSA to PEM format. convertToPublic: When it is equal to true, the RSA containing the private key will only return the public key, and the RSA containing only the public key will not be affected. privateUsePKCS8: The return format of the private key, when it is equal to true, it returns the PKCS#8 format (-----BEGIN PRIVATE KEY-----), otherwise returns PKCS#1 format (-----BEGIN RSA PRIVATE KEY-----), this parameter is invalid when returning a public key; Both formats are used more commonly. publicUsePKCS8: The return format of the public key, when it is equal to true, it returns the PKCS#8 format (-----BEGIN PUBLIC KEY-----), otherwise returns PKCS#1 format (-----BEGIN RSA PUBLIC KEY-----), this parameter is invalid when returning the private key; Generally, the true PKCS#8 format public key is mostly used, and the PKCS#1 format public key seems to be relatively rare.

string ToPEM_PKCS1(bool convertToPublic=false): Simplified writing of the ToPEM method, regardless of the public key or the private key, it returns the PKCS#1 format; it seems that the export of the PKCS#1 public key is less used, and the PKCS#8 public key is used more, and the private key #1#8 is almost.

string ToPEM_PKCS8(bool convertToPublic=false): Simplified writing of the ToPEM method, regardless of whether the public key or the private key returns the PKCS#8 format.

string ToXML(bool convertToPublic): Convert the key in RSA to XML format. If convertToPublic, the RSA containing the private key will only return the public key, and the RSA containing only the public key will not be affected.

RSA_Util Class Documentation

The RSA_Util.cs file depends on RSA_PEM.cs, which encapsulates encryption, decryption, signature, verification, and key import and export operations; .NET Core is supported by the actual RSA implementation class, .NET Framework 4.5 and below is supported by RSACryptoServiceProvider, .NET Framework 4.6 and above is supported by RSACng; or the BouncyCastle encryption enhancement library is introduced to provide support.

Static Attributes and Methods

string RSAPadding_Enc(string padding): Convert the encryption padding into the corresponding Algorithm string, such as: PKCS1 -> RSA/ECB/PKCS1Padding.

string RSAPadding_Sign(string hash): Convert the signature padding into the corresponding Algorithm string, such as: PKCS1+SHA1 -> SHA1withRSA.

bool IsDotNetSupportError(string errMsg): Determine whether the exception message is an error caused by .NET compatibility.

void UseBouncyCastle(Assembly bouncyCastleAssembly): Forces the use of the BouncyCastle cryptographic enhancement library for RSA operations. Just call it once after the program starts, directly call the class in BouncyCastle, pass in the assembly: UseBouncyCastle(typeof(RsaEngine).Assembly), pass in null to cancel the use. The project introduces the BouncyCastle encryption enhancement library to expand the .NET encryption function, NuGet: Portable.BouncyCastle or BouncyCastle.Cryptography, document https://www.bouncycastle.org/csharp/, call this method to register when the program starts to get All encrypted signature padding are supported.

bool IsUseBouncyCastle: Whether to force the use of the BouncyCastle encryption enhancement library for RSA operations. When true, .NET RSA will not be used.

bool IS_CORE: Whether the current running environment is .NET Core, false is .NET Framework.

Construction Methods

RSA_Util(int keySize): Create a new RSA with the specified key size, a new key will be generated, and an exception will be thrown if an error occurs.

RSA_Util(string pemOrXML): Create an RSA with a key in PEM or XML format, which can be a public key or a private key, and throws an exception if an error occurs. XML format such as: <RSAKeyValue><Modulus>...</RSAKeyValue>. pem supports PKCS#1, PKCS#8 format, the format is as follows: -----BEGIN XXX KEY-----....-----END XXX KEY-----.

RSA_Util(RSA_PEM pem): Create RSA through a pem object, where pem is a public key or private key, and an exception is thrown if an error occurs.

RSA_Util(byte[] modulus, byte[] exponent, byte[] d, byte[] p, byte[] q, byte[] dp, byte[] dq, byte[] inverseQ): This method will first generate RSA_PEM and then create RSA. Construct a PEM through the full amount of PEM field data. Except for the modulus and public key exponent, all other private key exponent information must be provided or not provided (the exported PEM only contains the public key). Note: all parameters If the first byte is 0, it must be removed first.

RSA_Util(byte[] modulus, byte[] exponent, byte[] dOrNull): This method will first generate RSA_PEM and then create RSA. Constructing a PEM through the public key exponent and the private key exponent will calculate P and Q in reverse, but they are extremely unlikely to be the same as the P and Q of the original generated key. Note: If the first byte of all parameters is 0, it must be removed first. Errors will throw exceptions. The private key exponent may not be provided, and the exported PEM only contains the public key.

Instance Attributes

RSA RSAObject: Get RSA object, the actual RSA implementation class under .NET Core, RSACryptoServiceProvider under .NET Framework 4.5 and below, RSACng under .NET Framework 4.6 and above; Note: .NET RSA will not be used when IsUseBouncyCastle.

bool RSAIsUseCore: Whether the used RSA object is the used .NET Core (RSA), otherwise it will be the used .NET Framework (4.5 and below RSACryptoServiceProvider, 4.6 and above RSACng); Note: When IsUseBouncyCastle will not use .NET RSA.

int KeySize: Key digits.

bool HasPrivate: Whether to include the private key.

Instance Methods

string ToXML(bool convertToPublic = false): Export the secret key in XML format. If the RSA contains a private key, the private key will be exported by default. When only the public key is set, only the public key will be exported; if the private key is not included, only the public key will be exported.

RSA_PEM ToPEM(bool convertToPublic = false): Export RSA_PEM object (then you can export PEM text by RSA_PEM.ToPEM method), if convertToPublic RSA containing private key will only return public key, RSA containing only public key will not be affected.

RSA_Util SwapKey_Exponent_D__Unsafe(): [Unsafe and not recommended] Swap the public key exponent (Key_Exponent) and the private key exponent (Key_D): use the public key as the private key (new.Key_D=this.Key_Exponent) and the private key as the public key (new.Key_Exponent=this.Key_D), returns a new RSA object; for example, used for: private key encryption, public key decryption, this is an unconventional usage. If the current key only contains the public key, the swap will not occur, and the returned new RSA will allow decryption and signing operations with the public key; However, the RSA that comes with .NET does not support decryption and signing with keys containing only the public key, and the exponent must be swapped (If it is .NET Framework 4.5 and below, public and private keys are not supported), there is no such problem when using NoPadding or IsUseBouncyCastle. Note: It is very unsafe to use a public key as a private key, because the public key exponent of most generated keys is 0x10001 (AQAB), which is too easy to guess and cannot be used as a true private key. In some private key encryption implementations, such as Java's own RSA, when using non-NoPadding padding, encryption with private key objects may use EMSA-PKCS1-v1_5 padding (using the private key exponent to construct a public key object does not have this problem ), so when interoperating between different programs, you may need to use the corresponding padding algorithm to first fill the data, and then use NoPadding padding to encrypt (decryption also uses NoPadding padding to decrypt, and then remove the padding data).

string Encrypt(string padding, string str): Encrypt arbitrary length string (utf-8) returns base64, and an exception is thrown if an error occurs. This method is thread safe. padding specifies the encryption padding, such as: PKCS1, OAEP+SHA256 uppercase, refer to the encryption padding table above, and the default is PKCS1 when using a null value.

byte[] Encrypt(string padding, byte[] data): Encrypt arbitrary length data, and throw an exception if an error occurs. This method is thread safe.

string Decrypt(string padding, string str): Decrypt arbitrary length ciphertext (base64) to get string (utf-8), and throw an exception if an error occurs. This method is thread safe. padding specifies the encryption padding, such as: PKCS1, OAEP+SHA256 uppercase, refer to the encryption padding table above, and the default is PKCS1 when using a null value.

byte[] Decrypt(string padding, byte[] data): Decrypt arbitrary length data, and throw an exception if an error occurs. This method is thread safe.

string Sign(string hash, string str): Sign the string str, return the base64 result, and throw an exception if an error occurs. This method is thread safe. hash specifies the signature digest algorithm and signature padding, such as: SHA256, PSS+SHA1 uppercase, refer to the signature padding table above.

byte[] Sign(string hash, byte[] data): Sign the data, and throw an exception if an error occurs. This method is thread safe.

bool Verify(string hash, string sign, string str): Verify whether the signature of the string str is sign (base64), and throw an exception if an error occurs. This method is thread safe. hash specifies the signature digest algorithm and signature padding, such as: SHA256, PSS+SHA1 uppercase, refer to the signature padding table above.

bool Verify(string hash, byte[] sign, byte[] data): Verify whether the signature of data is sign, and throw an exception if an error occurs. This method is thread safe.

OpenSSL RSA common command line reference

::First prepare a test file test.txt and fill in a small amount of content, openssl does not support automatic segmentation encryption

::Generate new key
openssl genrsa -out private.pem 1024

::Extract public key PKCS#8
openssl rsa -in private.pem -pubout -out public.pem

::Convert to RSAPublicKey PKCS#1
openssl rsa -pubin -in public.pem -RSAPublicKey_out -out public.pem.rsakey
::Test RSAPublicKey PKCS#1, no accident will go wrong. Because there is no OID in this public key, it can be encrypted normally by converting RSA_PEM into PKCS#8 and automatically bringing OID
echo abcd123 | openssl rsautl -encrypt -inkey public.pem.rsakey -pubin



::Encryption and decryption, padding mode: PKCS1
openssl pkeyutl -encrypt -pkeyopt rsa_padding_mode:pkcs1 -in test.txt -pubin -inkey public.pem -out test.txt.enc.bin
openssl pkeyutl -decrypt -pkeyopt rsa_padding_mode:pkcs1 -in test.txt.enc.bin -inkey private.pem -out test.txt.dec.txt

::Encryption and decryption, padding mode: OAEP+SHA256, mask generation function MGF1 uses the same hash algorithm
openssl pkeyutl -encrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -in test.txt -pubin -inkey public.pem -out test.txt.enc.bin
openssl pkeyutl -decrypt -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -in test.txt.enc.bin -inkey private.pem -out test.txt.dec.txt


::The sha256 in the command line parameters can be replaced by md5, sha1, etc.; if you need the sha3 series, you can replace it with sha3-256


::Signature and verification, padding mode: PKCS1+SHA256
openssl dgst -sha256 -binary -sign private.pem -out test.txt.sign.bin test.txt
openssl dgst -sha256 -binary -verify public.pem -signature test.txt.sign.bin test.txt

::Signature and verification, padding mode: PSS+SHA256, salt=-1 use hash length=256/8, mask generation function MGF1 uses the same hash algorithm
openssl dgst -sha256 -binary -out test.txt.hash test.txt
openssl pkeyutl -sign -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:-1 -in test.txt.hash -inkey private.pem -out test.txt.sign.bin
openssl pkeyutl -verify -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:-1 -in test.txt.hash -pubin -inkey public.pem -sigfile test.txt.sign.bin

⭐Donate

If this library is helpful to you, please star it.

You can also use Alipay or WeChat to donate to the author: