Laravel Decrypter
The documentation on the topic Encrypting A Value, explained that developers can use encryptString
function from Crypt
module likes:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
class DigitalOceanTokenController extends Controller
{
/**
* Store a DigitalOcean API token for the user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function storeSecret(Request $request)
{
$request->user()->fill([
'token' => Crypt::encryptString($request->token),
])->save();
}
All the ciphertext results are encrypted with AES-256-CBC chiper. And on some occasional event, there is a requirement to decrypt the value from non-technical people who do not code.
So, I try to create laravel_decrypt. A tool written in Rust and using egui for the user interface.
egui
Egui is an easy-to-use immediate mode GUI which can be compiled and targetted into multiple platforms (Mac, Windows, Linux, and Web), example:
...
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
ui.horizontal(|ui| {
ui.label("Your name: ");
ui.text_edit_singleline(&mut self.name);
});
ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
if ui.button("Click each year").clicked() {
self.age += 1;
}
ui.label(format!("Hello '{}', age {}", self.name, self.age));
});
}
}
...
Decryption
For doing encryption aes, base64, block-modes and serde_json creates are used.
Chipertext wrapped in base64 encoding, after decoding it will output JSON object with three keys: iv
, value
, and mac
.
pub fn parse_ciphertext(ciphertext: &str) -> Result<LaravelEncryptedData, String> {
let payload = match base64::decode(ciphertext) {
Ok(v) => v,
Err(_) => return Err("failed to decode base64".to_owned()),
};
match serde_json::from_slice(&payload) {
Ok(v) => Ok(v),
Err(e) => Err(e.to_string()),
}
}
To convert it to plain text without authentication, we need key
, ciphertext
, and iv
.
pub fn decrypt(key: Vec<u8>, ciphertext: Vec<u8>, iv: Vec<u8>) -> Result<String, String> {
let cipher = match Aes256Cbc::new_from_slices(&key, &iv) {
Ok(v) => v,
Err(e) => return Err(e.to_string()),
};
let data = match cipher.decrypt_vec(&ciphertext) {
Ok(v) => v,
Err(e) => return Err(e.to_string()),
};
Ok(String::from_utf8_lossy(&data).to_string())
}
For full source-code, you can visit https://github.com/sakti/laravel_decrypt.