Skip to main content

rsa/
lib.rs

1#![cfg_attr(not(test), no_std)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
5#![warn(missing_docs)]
6#![cfg_attr(not(test), deny(clippy::unwrap_used))]
7
8//! # Supported algorithms
9//!
10//! This crate supports several schemes described in [RFC8017]:
11//!
12//! - [OAEP encryption scheme](#oaep-encryption)
13//! - [PKCS#1 v1.5 encryption scheme](#pkcs1-v15-encryption)
14//! - [PKCS#1 v1.5 signature scheme](#pkcs1-v15-signatures)
15//! - [PSS signature scheme](#pss-signatures)
16//!
17//! These schemes are described below.
18//!
19//! # Usage
20//!
21//! ## OAEP encryption
22//!
23//! Note: requires `sha2` feature of `rsa` crate is enabled.
24//!
25#![cfg_attr(feature = "sha2", doc = "```")]
26#![cfg_attr(not(feature = "sha2"), doc = "```ignore")]
27//! use rsa::{RsaPrivateKey, RsaPublicKey, Oaep, sha2::Sha256};
28//!
29//! let mut rng = rand::rng();
30//!
31//! let bits = 2048;
32//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
33//! let public_key = RsaPublicKey::from(&private_key);
34//!
35//! // Encrypt
36//! let data = b"hello world";
37//! let padding = Oaep::<Sha256>::new();
38//! let enc_data = public_key.encrypt(&mut rng, padding, &data[..]).expect("failed to encrypt");
39//! assert_ne!(&data[..], &enc_data[..]);
40//!
41//! // Decrypt
42//! let padding = Oaep::<Sha256>::new();
43//! let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt");
44//! assert_eq!(&data[..], &dec_data[..]);
45//! ```
46//!
47//! ## PKCS#1 v1.5 encryption
48//!
49//! <div class="warning">
50//! <b>Warning:</b>
51//! See security notes in the <code><a href="./pkcs1v15/index.html">pkcs1v15</a></code> module.
52//! </div>
53//!
54//! ```
55//! use rsa::{RsaPrivateKey, RsaPublicKey, Pkcs1v15Encrypt};
56//!
57//! let mut rng = rand::rng();
58//!
59//! let bits = 2048;
60//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
61//! let public_key = RsaPublicKey::from(&private_key);
62//!
63//! // Encrypt
64//! let data = b"hello world";
65//! let enc_data = public_key.encrypt(&mut rng, Pkcs1v15Encrypt, &data[..]).expect("failed to encrypt");
66//! assert_ne!(&data[..], &enc_data[..]);
67//!
68//! // Decrypt
69//! let dec_data = private_key.decrypt(Pkcs1v15Encrypt, &enc_data).expect("failed to decrypt");
70//! assert_eq!(&data[..], &dec_data[..]);
71//! ```
72//!
73//! ## PKCS#1 v1.5 signatures
74//!
75//! <div class="warning">
76//! <b>Warning:</b>
77//! See security notes in the <code><a href="./pkcs1v15/index.html">pkcs1v15</a></code> module.
78//! </div>
79//!
80//! Note: requires `sha2` feature of `rsa` crate is enabled.
81//!
82#![cfg_attr(feature = "sha2", doc = "```")]
83#![cfg_attr(not(feature = "sha2"), doc = "```ignore")]
84//! use rsa::RsaPrivateKey;
85//! use rsa::pkcs1v15::{SigningKey, VerifyingKey};
86//! use rsa::signature::{Keypair, RandomizedSigner, SignatureEncoding, Verifier};
87//! use rsa::sha2::{Digest, Sha256};
88//!
89//! let mut rng = rand::rng();
90//!
91//! let bits = 2048;
92//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
93//! let signing_key = SigningKey::<Sha256>::new(private_key);
94//! let verifying_key = signing_key.verifying_key();
95//!
96//! // Sign
97//! let data = b"hello world";
98//! let signature = signing_key.sign_with_rng(&mut rng, data);
99//! assert_ne!(signature.to_bytes().as_ref(), data.as_slice());
100//!
101//! // Verify
102//! verifying_key.verify(data, &signature).expect("failed to verify");
103//! ```
104//!
105//! ## PSS signatures
106//!
107//! Note: requires `sha2` feature of `rsa` crate is enabled.
108//!
109#![cfg_attr(feature = "sha2", doc = "```")]
110#![cfg_attr(not(feature = "sha2"), doc = "```ignore")]
111//! use rsa::RsaPrivateKey;
112//! use rsa::pss::{BlindedSigningKey, VerifyingKey};
113//! use rsa::signature::{Keypair,RandomizedSigner, SignatureEncoding, Verifier};
114//! use rsa::sha2::{Digest, Sha256};
115//!
116//! let mut rng = rand::rng();
117//!
118//! let bits = 2048;
119//! let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
120//! let signing_key = BlindedSigningKey::<Sha256>::new(private_key);
121//! let verifying_key = signing_key.verifying_key();
122//!
123//! // Sign
124//! let data = b"hello world";
125//! let signature = signing_key.sign_with_rng(&mut rng, data);
126//! assert_ne!(signature.to_bytes().as_ref(), data);
127//!
128//! // Verify
129//! verifying_key.verify(data, &signature).expect("failed to verify");
130//! ```
131//!
132//! ## PKCS#1 RSA Key Encoding
133//!
134//! PKCS#1 supports a legacy format for encoding RSA keys as binary (DER) or
135//! text (PEM) data.
136//!
137//! You can recognize PEM encoded PKCS#1 keys because they have "RSA * KEY" in
138//! the type label, e.g.:
139//!
140//! ```text
141//! -----BEGIN RSA PRIVATE KEY-----
142//! ```
143//!
144//! Most modern applications use the newer PKCS#8 format instead (see below).
145//!
146//! The following traits can be used to decode/encode [`RsaPrivateKey`] and
147//! [`RsaPublicKey`] as PKCS#1. Note that [`pkcs1`] is re-exported from the
148//! toplevel of the `rsa` crate:
149//!
150//! - [`pkcs1::DecodeRsaPrivateKey`]: decode RSA private keys from PKCS#1
151//! - [`pkcs1::EncodeRsaPrivateKey`]: encode RSA private keys to PKCS#1
152//! - [`pkcs1::DecodeRsaPublicKey`]: decode RSA public keys from PKCS#1
153//! - [`pkcs1::EncodeRsaPublicKey`]: encode RSA public keys to PKCS#1
154//!
155//! ### Example
156//!
157//! ```
158//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
159//! # #[cfg(all(feature = "encoding", feature = "std"))]
160//! # {
161//! use rsa::{RsaPublicKey, pkcs1::DecodeRsaPublicKey};
162//!
163//! let pem = "-----BEGIN RSA PUBLIC KEY-----
164//! MIIBCgKCAQEAtsQsUV8QpqrygsY+2+JCQ6Fw8/omM71IM2N/R8pPbzbgOl0p78MZ
165//! GsgPOQ2HSznjD0FPzsH8oO2B5Uftws04LHb2HJAYlz25+lN5cqfHAfa3fgmC38Ff
166//! wBkn7l582UtPWZ/wcBOnyCgb3yLcvJrXyrt8QxHJgvWO23ITrUVYszImbXQ67YGS
167//! 0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0NfFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J
168//! 9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejIn04APPKIjpMyQdnWlby7rNyQtE4+CV+j
169//! cFjqJbE/Xilcvqxt6DirjFCvYeKYl1uHLwIDAQAB
170//! -----END RSA PUBLIC KEY-----";
171//!
172//! let public_key = RsaPublicKey::from_pkcs1_pem(pem)?;
173//! # }
174//! # Ok(())
175//! # }
176//! ```
177//!
178//! ## PKCS#8 RSA Key Encoding
179//!
180//! PKCS#8 is a private key format with support for multiple algorithms.
181//! Like PKCS#1, it can be encoded as binary (DER) or text (PEM).
182//!
183//! You can recognize PEM encoded PKCS#8 keys because they *don't* have
184//! an algorithm name in the type label, e.g.:
185//!
186//! ```text
187//! -----BEGIN PRIVATE KEY-----
188//! ```
189//!
190//! The following traits can be used to decode/encode [`RsaPrivateKey`] and
191//! [`RsaPublicKey`] as PKCS#8. Note that [`pkcs8`] is re-exported from the
192//! toplevel of the `rsa` crate:
193//!
194//! - [`pkcs8::DecodePrivateKey`]: decode private keys from PKCS#8
195//! - [`pkcs8::EncodePrivateKey`]: encode private keys to PKCS#8
196//! - [`pkcs8::DecodePublicKey`]: decode public keys from PKCS#8
197//! - [`pkcs8::EncodePublicKey`]: encode public keys to PKCS#8
198//!
199//! ### Example
200//!
201//! ```
202//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
203//! # #[cfg(all(feature = "encoding", feature = "std"))]
204//! # {
205//! use rsa::{RsaPublicKey, pkcs8::DecodePublicKey};
206//!
207//! let pem = "-----BEGIN PUBLIC KEY-----
208//! MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtsQsUV8QpqrygsY+2+JC
209//! Q6Fw8/omM71IM2N/R8pPbzbgOl0p78MZGsgPOQ2HSznjD0FPzsH8oO2B5Uftws04
210//! LHb2HJAYlz25+lN5cqfHAfa3fgmC38FfwBkn7l582UtPWZ/wcBOnyCgb3yLcvJrX
211//! yrt8QxHJgvWO23ITrUVYszImbXQ67YGS0YhMrbixRzmo2tpm3JcIBtnHrEUMsT0N
212//! fFdfsZhTT8YbxBvA8FdODgEwx7u/vf3J9qbi4+Kv8cvqyJuleIRSjVXPsIMnoejI
213//! n04APPKIjpMyQdnWlby7rNyQtE4+CV+jcFjqJbE/Xilcvqxt6DirjFCvYeKYl1uH
214//! LwIDAQAB
215//! -----END PUBLIC KEY-----";
216//!
217//! let public_key = RsaPublicKey::from_public_key_pem(pem)?;
218//! # }
219//! # Ok(())
220//! # }
221//! ```
222//!
223//! [RFC8017]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.1
224//!
225// TODO(tarcieri): figure out why rustdoc isn't rendering these links correctly
226//! [`pkcs8::DecodePublicKey`]: https://docs.rs/pkcs8/latest/pkcs8/trait.DecodePublicKey.html
227//! [`pkcs8::EncodePublicKey`]: https://docs.rs/pkcs8/latest/pkcs8/trait.EncodePublicKey.html
228
229#[cfg(doctest)]
230pub struct ReadmeDoctests;
231
232#[macro_use]
233extern crate alloc;
234#[cfg(feature = "std")]
235extern crate std;
236
237pub use crypto_bigint::BoxedUint;
238pub use rand_core;
239pub use signature;
240
241mod algorithms;
242pub mod errors;
243pub mod oaep;
244pub mod pkcs1v15;
245pub mod pss;
246pub mod traits;
247
248mod dummy_rng;
249mod encoding;
250mod key;
251
252#[cfg(feature = "encoding")]
253pub use pkcs1;
254#[cfg(feature = "encoding")]
255pub use pkcs8;
256#[cfg(feature = "sha2")]
257pub use sha2;
258
259pub use crate::{
260    errors::{Error, Result},
261    key::{RsaPrivateKey, RsaPublicKey},
262    oaep::Oaep,
263    pkcs1v15::{Pkcs1v15Encrypt, Pkcs1v15Sign},
264    pss::Pss,
265    traits::keys::CrtValue,
266};
267
268#[cfg(feature = "hazmat")]
269pub mod hazmat;