Laravel Decrypter

on Sakti's blog

Laravel decrypter tool

One of Laravel's security features is Encryption. This feature creates a convenient interface for encrypting and decrypting via OpenSSL.

The documentation on the topic Encrypting A Value, explained that developers can use encryptString function from Crypt module likes:

 1<?php
 2 
 3namespace App\Http\Controllers;
 4 
 5use App\Http\Controllers\Controller;
 6use App\Models\User;
 7use Illuminate\Http\Request;
 8use Illuminate\Support\Facades\Crypt;
 9 
10class DigitalOceanTokenController extends Controller
11{
12    /**
13     * Store a DigitalOcean API token for the user.
14     *
15     * @param  \Illuminate\Http\Request  $request
16     * @return \Illuminate\Http\Response
17     */
18    public function storeSecret(Request $request)
19    {
20        $request->user()->fill([
21            'token' => Crypt::encryptString($request->token),
22        ])->save();
23    }

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:

 1...
 2impl eframe::App for MyApp {
 3    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
 4        egui::CentralPanel::default().show(ctx, |ui| {
 5            ui.heading("My egui Application");
 6            ui.horizontal(|ui| {
 7                ui.label("Your name: ");
 8                ui.text_edit_singleline(&mut self.name);
 9            });
10            ui.add(egui::Slider::new(&mut self.age, 0..=120).text("age"));
11            if ui.button("Click each year").clicked() {
12                self.age += 1;
13            }
14            ui.label(format!("Hello '{}', age {}", self.name, self.age));
15        });
16    }
17}
18...
19

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.

 1pub fn parse_ciphertext(ciphertext: &str) -> Result<LaravelEncryptedData, String> {
 2    let payload = match base64::decode(ciphertext) {
 3        Ok(v) => v,
 4        Err(_) => return Err("failed to decode base64".to_owned()),
 5    };
 6    match serde_json::from_slice(&payload) {
 7        Ok(v) => Ok(v),
 8        Err(e) => Err(e.to_string()),
 9    }
10}

To convert it to plain text without authentication, we need key, ciphertext, and iv.

 1pub fn decrypt(key: Vec<u8>, ciphertext: Vec<u8>, iv: Vec<u8>) -> Result<String, String> {
 2    let cipher = match Aes256Cbc::new_from_slices(&key, &iv) {
 3        Ok(v) => v,
 4        Err(e) => return Err(e.to_string()),
 5    };
 6    let data = match cipher.decrypt_vec(&ciphertext) {
 7        Ok(v) => v,
 8        Err(e) => return Err(e.to_string()),
 9    };
10    Ok(String::from_utf8_lossy(&data).to_string())
11}

For full source-code, you can visit https://github.com/sakti/laravel_decrypt.