magic_crypt/
lib.rs

1/*!
2# MagicCrypt
3
4MagicCrypt is a Java/PHP/NodeJS/Rust library to encrypt/decrypt strings, files, or data, using Data Encryption Standard(DES) or Advanced Encryption Standard(AES) algorithms. It supports CBC block cipher mode, PKCS7 padding and 64, 128, 192 or 256-bits key length.
5
6## For Rust
7
8### Example
9
10```rust
11use magic_crypt::{new_magic_crypt, MagicCryptTrait};
12
13let mc = new_magic_crypt!("magickey", 256);
14
15let base64 = mc.encrypt_str_to_base64("http://magiclen.org");
16
17assert_eq!("DS/2U8royDnJDiNY2ps3f6ZoTbpZo8ZtUGYLGEjwLDQ=", base64);
18
19assert_eq!("http://magiclen.org", mc.decrypt_base64_to_string(&base64).unwrap());
20```
21
22## Change the Buffer Size
23
24The default buffer size for the `encrypt_reader_to_writer` method and the `decrypt_reader_to_writer` method is 4096 bytes. If you want to change that, you can use the `encrypt_reader_to_writer2` method or the `decrypt_reader_to_writer2` method, and define a length explicitly.
25
26For example, to change the buffer size to 256 bytes,
27
28```rust
29use std::io::Cursor;
30
31use base64::Engine;
32use magic_crypt::{new_magic_crypt, MagicCryptTrait};
33use magic_crypt::generic_array::typenum::U256;
34
35let mc = new_magic_crypt!("magickey", 256);
36
37# #[cfg(feature = "std")] {
38let mut reader = Cursor::new("http://magiclen.org");
39let mut writer = Vec::new();
40
41mc.encrypt_reader_to_writer2::<U256>(&mut reader, &mut writer).unwrap();
42
43let base64 = base64::engine::general_purpose::STANDARD.encode(&writer);
44
45assert_eq!("DS/2U8royDnJDiNY2ps3f6ZoTbpZo8ZtUGYLGEjwLDQ=", base64);
46
47assert_eq!("http://magiclen.org", mc.decrypt_base64_to_string(&base64).unwrap());
48# }
49```
50
51## No Std
52
53Disable the default features to compile this crate without std.
54
55```toml
56[dependencies.magic-crypt]
57version = "*"
58default-features = false
59```
60
61## For Java
62
63Refer to https://github.com/magiclen/MagicCrypt.
64
65## For PHP
66
67Refer to https://github.com/magiclen/MagicCrypt.
68
69## For NodeJS
70
71Refer to https://github.com/magiclen/node-magiccrypt
72*/
73
74#![cfg_attr(not(feature = "std"), no_std)]
75
76extern crate alloc;
77
78mod ciphers;
79mod errors;
80mod functions;
81mod macros;
82mod secure_bit;
83mod traits;
84
85use alloc::vec::Vec;
86#[cfg(feature = "std")]
87use std::io::{Read, Write};
88#[cfg(feature = "std")]
89use std::ops::Add;
90
91pub use cbc::cipher::generic_array;
92pub use ciphers::{
93    aes128::MagicCrypt128, aes192::MagicCrypt192, aes256::MagicCrypt256, des64::MagicCrypt64,
94};
95pub use errors::MagicCryptError;
96#[cfg(feature = "std")]
97use generic_array::typenum::{IsGreaterOrEqual, PartialDiv, True, B1, U16};
98#[cfg(feature = "std")]
99use generic_array::ArrayLength;
100pub use secure_bit::SecureBit;
101pub use traits::MagicCryptTrait;
102
103#[derive(Debug, Clone)]
104enum MagicCryptCipher {
105    DES64(MagicCrypt64),
106    AES128(MagicCrypt128),
107    AES192(MagicCrypt192),
108    AES256(MagicCrypt256),
109}
110
111/// This struct can help you encrypt or decrypt data in a quick way.
112#[derive(Debug, Clone)]
113pub struct MagicCrypt {
114    cipher: MagicCryptCipher,
115}
116
117impl MagicCrypt {
118    /// Create a new `MagicCrypt` instance. You may want to use the `new_magic_crypt!` macro.
119    pub fn new<S: AsRef<[u8]>, V: AsRef<[u8]>>(
120        key: S,
121        bit: SecureBit,
122        iv: Option<V>,
123    ) -> MagicCrypt {
124        let cipher = match bit {
125            SecureBit::Bit64 => MagicCryptCipher::DES64(MagicCrypt64::new(key, iv)),
126            SecureBit::Bit128 => MagicCryptCipher::AES128(MagicCrypt128::new(key, iv)),
127            SecureBit::Bit192 => MagicCryptCipher::AES192(MagicCrypt192::new(key, iv)),
128            SecureBit::Bit256 => MagicCryptCipher::AES256(MagicCrypt256::new(key, iv)),
129        };
130
131        MagicCrypt {
132            cipher,
133        }
134    }
135}
136
137impl MagicCryptTrait for MagicCrypt {
138    #[inline]
139    fn new<S: AsRef<[u8]>, V: AsRef<[u8]>>(key: S, iv: Option<V>) -> MagicCrypt {
140        MagicCrypt::new(key, SecureBit::default(), iv)
141    }
142
143    #[inline]
144    fn encrypt_to_bytes<T: ?Sized + AsRef<[u8]>>(&self, data: &T) -> Vec<u8> {
145        match &self.cipher {
146            MagicCryptCipher::DES64(mc) => mc.encrypt_to_bytes(data),
147            MagicCryptCipher::AES128(mc) => mc.encrypt_to_bytes(data),
148            MagicCryptCipher::AES192(mc) => mc.encrypt_to_bytes(data),
149            MagicCryptCipher::AES256(mc) => mc.encrypt_to_bytes(data),
150        }
151    }
152
153    #[cfg(feature = "std")]
154    #[inline]
155    fn encrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
156        match &self.cipher {
157            MagicCryptCipher::DES64(mc) => mc.encrypt_reader_to_bytes(reader),
158            MagicCryptCipher::AES128(mc) => mc.encrypt_reader_to_bytes(reader),
159            MagicCryptCipher::AES192(mc) => mc.encrypt_reader_to_bytes(reader),
160            MagicCryptCipher::AES256(mc) => mc.encrypt_reader_to_bytes(reader),
161        }
162    }
163
164    #[cfg(feature = "std")]
165    #[inline]
166    fn encrypt_reader_to_writer2<
167        N: ArrayLength<u8> + PartialDiv<U16> + IsGreaterOrEqual<U16, Output = True>,
168    >(
169        &self,
170        reader: &mut dyn Read,
171        writer: &mut dyn Write,
172    ) -> Result<(), MagicCryptError> {
173        match &self.cipher {
174            MagicCryptCipher::DES64(mc) => mc.encrypt_reader_to_writer2::<N>(reader, writer),
175            MagicCryptCipher::AES128(mc) => mc.encrypt_reader_to_writer2::<N>(reader, writer),
176            MagicCryptCipher::AES192(mc) => mc.encrypt_reader_to_writer2::<N>(reader, writer),
177            MagicCryptCipher::AES256(mc) => mc.encrypt_reader_to_writer2::<N>(reader, writer),
178        }
179    }
180
181    #[inline]
182    fn decrypt_bytes_to_bytes<T: ?Sized + AsRef<[u8]>>(
183        &self,
184        bytes: &T,
185    ) -> Result<Vec<u8>, MagicCryptError> {
186        match &self.cipher {
187            MagicCryptCipher::DES64(mc) => mc.decrypt_bytes_to_bytes(bytes),
188            MagicCryptCipher::AES128(mc) => mc.decrypt_bytes_to_bytes(bytes),
189            MagicCryptCipher::AES192(mc) => mc.decrypt_bytes_to_bytes(bytes),
190            MagicCryptCipher::AES256(mc) => mc.decrypt_bytes_to_bytes(bytes),
191        }
192    }
193
194    #[cfg(feature = "std")]
195    #[inline]
196    fn decrypt_reader_to_bytes(&self, reader: &mut dyn Read) -> Result<Vec<u8>, MagicCryptError> {
197        match &self.cipher {
198            MagicCryptCipher::DES64(mc) => mc.decrypt_reader_to_bytes(reader),
199            MagicCryptCipher::AES128(mc) => mc.decrypt_reader_to_bytes(reader),
200            MagicCryptCipher::AES192(mc) => mc.decrypt_reader_to_bytes(reader),
201            MagicCryptCipher::AES256(mc) => mc.decrypt_reader_to_bytes(reader),
202        }
203    }
204
205    #[cfg(feature = "std")]
206    #[inline]
207    fn decrypt_reader_to_writer2<
208        N: ArrayLength<u8> + PartialDiv<U16> + IsGreaterOrEqual<U16, Output = True> + Add<B1>,
209    >(
210        &self,
211        reader: &mut dyn Read,
212        writer: &mut dyn Write,
213    ) -> Result<(), MagicCryptError>
214    where
215        <N as Add<B1>>::Output: ArrayLength<u8>, {
216        match &self.cipher {
217            MagicCryptCipher::DES64(mc) => mc.decrypt_reader_to_writer(reader, writer),
218            MagicCryptCipher::AES128(mc) => mc.decrypt_reader_to_writer(reader, writer),
219            MagicCryptCipher::AES192(mc) => mc.decrypt_reader_to_writer(reader, writer),
220            MagicCryptCipher::AES256(mc) => mc.decrypt_reader_to_writer(reader, writer),
221        }
222    }
223}