在開發程式的時候,我們可能會需要隱藏敏感的資料,讓一般使用者不會直接看到,例如流水序號、密碼、網頁Cookie等。這樣的資料通常都很小,可能只有數個位元組,但如果使用AES/DES加密,密文(也就是加密後的資料)都至少有16個位元組以上!實在不太適合用來加密這樣的少量資料。
在某些情況下,我們必須或是最好使用短密文。例如網址,人們通常偏好使用比較短的網址,甚至還會去使用「短網址」服務,因為短的網址其識別性更高,看起來更討喜,而且也更容易被傳播。另外就是條碼,條碼的物理空間和資料空間有限,過大的資料量會需要更大的面積來印條碼,因此想辦法減少條碼包含的資料量是很重要的課題。除此之外,需要透過網路傳輸的資料,如網頁Cookie等等,更短的資料量也可以讓傳輸速度變快,減少流量消耗。
ShortCrypt
ShortCrypt是一個跨程式語言的資料加解密函式庫,特點在於其密文只比明文(原始資料)還要大4個位元(半個位元組),非常適合用在需要短密文的條件下。此外,就算要加密的資料只有一位元組的差異,ShortCrypt所加密出來的密文也不會長得很像,不太需要擔心因為密文短就容易被猜出明文。
在Rust上使用ShortCrypt
Crates.io
Cargo.toml
使用方法
使用use
關鍵字來將short_crypt
這個crate底下的ShortCrypt
結構體給引用到當前的程式範圍下,透過ShortCrypt
結構體提供的new
關聯函數,可以從參數傳入要用來加解密的密鑰字串,來建立出ShortCrypt
結構實體。
use short_crypt::ShortCrypt;
fn main() {
let sc = ShortCrypt::new("magickey");
}
加密
有了ShortCrypt
結構實體之後,就可以使用encrypt
方法來加密任意資料了!encrypt
方法可以將透過參數傳入的資料,加密成由一個u8
數值和一個Vec<u8>
結構實體組成的元組(tuple)。前者即為那多出來的「4位元」,後者為加密後的資料,其大小等於透過參數傳入至encrypt
方法的資料。把前後兩者合在一起就是密文了!
例如:
use short_crypt::ShortCrypt;
fn main() {
let sc = ShortCrypt::new("magickey");
assert_eq!((8, [216, 78, 214, 199, 157, 190, 78, 250].to_vec()), sc.encrypt("articles"));
}
如果要將密文轉成字串,除了可以自己寫程式處理外,可以使用ShortCrypt
結構實體內建的encrypt_to_url_component
方法將資料加密成能夠用在URL上的字串,或是用encrypt_to_qr_code_alphanumeric
方法將資料加密成適合用在QR Code上的字串。
程式如下:
use short_crypt::ShortCrypt;
fn main() {
let sc = ShortCrypt::new("magickey");
assert_eq!("2E87Wx52-Tvo", sc.encrypt_to_url_component("articles"));
assert_eq!("3BHNNR45XZH8PU", sc.encrypt_to_qr_code_alphanumeric("articles"));
}
如果想要將字串結果串接到現有的字串之後,可以使用encrypt_to_url_component_and_push_to_string
或是encrypt_to_qr_code_alphanumeric_and_push_to_string
方法。
解密
使用ShortCrypt
結構實體的decrypt
方法,可以解密從參數傳入的密文。不管明文是不是字串,解密結果都會是Vec<u8>
結構實體。
例如:
use short_crypt::ShortCrypt;
fn main() {
let sc = ShortCrypt::new("magickey");
assert_eq!("articles".as_bytes().to_vec(), sc.decrypt(&(8, vec![216, 78, 214, 199, 157, 190, 78, 250])).unwrap());
}
如果密文是用剛才提過的encrypt_to_url_component
方法和encrypt_to_qr_code_alphanumeric
所產生出來的字串的話,則可以用decrypt_url_component
和decrypt_qr_code_alphanumeric
方法來解密。
程式如下:
use short_crypt::ShortCrypt;
fn main() {
let sc = ShortCrypt::new("magickey");
assert_eq!("articles".as_bytes().to_vec(), sc.decrypt_url_component("2E87Wx52-Tvo").unwrap());
assert_eq!("articles".as_bytes().to_vec(), sc.decrypt_qr_code_alphanumeric("3BHNNR45XZH8PU").unwrap());
}
如果要將解密出來的明文,直接串接到現有的Vec<u8>
結構實體之後,可以使用decrypt_url_component_and_push_to_vec
或是decrypt_qr_code_alphanumeric_and_push_to_vec
方法。
在JavaScript/TypeScript上使用ShortCrypt
npmjs.com
npm 安裝指令
使用方法
引入short-crypt
後,接著使用new
關鍵字來實體化出ShortCrypt
的物件,可以從參數傳入要用來加解密的密鑰字串。
import { ShortCrypt } from "short-crypt";
const sc = new ShortCrypt(key);
加密
ShortCrypt
物件有以下幾個與加密相關的方法:
-
encrypt
:加密從參數傳入的資料,回傳一個擁有base
和body
欄位的物件,這個物件即為密文。 -
encryptToURLComponent
:加密從參數傳入的資料,回傳一個能夠用在URL上的字串密文。 -
encryptToQRCodeAlphanumeric
:加密從參數傳入的資料,回傳一個適合用在QR Code上的字串密文。
只有字串和Byte陣列(Uint8Array
)可以被加密。
例如:
const cipher1 = sc.encryptToURLComponent(plainText);
const cipher2 = sc.encryptToQRCodeAlphanumeric(plainText);
解密
對應剛才提到的encrypt
、encryptToURLComponent
和encryptToQRCodeAlphanumeric
方法,ShortCrypt
的物件有提供decrypt
、decryptURLComponent
和decryptQRCodeAlphanumeric
方法,可以解密那些不同形式的密文。
例如:
const result1 = sc.decryptURLComponent(cipher1);
const result2 = sc.decryptQRCodeAlphanumeric(cipher2);