How can I encrypt an uploaded file using a public key?

Hi everyone

I am uploading files to the server using the usual File Upload action in SC. I want to encrypt the uploaded file using a public key so it’s secure and only decryptable by someone downloading the file and using the private key which is never uploaded to the server.

I’m thinking something like OpenSSL.

Can this be done in Wappler?

Cheers, Jon.

Hi Jon, this is called asymmetric encryption. Industry standard is something called PGP. Wappler would probably need a custom extension, I think Wappler only has symmetric encryption built-in formatters.

Symmetric encryption = you encrypt and decrypt with same password
Asymmetric encryption = you encrypt with public key and decrypt with private key

Thanks @Apple. Yep, I use both types in other ways of life. It’s using it in Wappler which I want to dig into.

Wappler does indeed only have symmetric encryption at the moment but how easy would it be to add asymmetric to it?

I’ll create a feature request.

UPDATE: Turns out I already put in this feature request 3 years ago!

Disclaimer: I'm not too familiar with PGP/GPG

Seems relatively easy, since PHP has built-in functions:

Easiest way would be to write Wappler formatters

Edit: Requires installation of GnuPG PHP extension

Thanks again. I want to encrypt uploaded files rather than simple text.

I’ve taken a leaf from @ben’s book and asked ChatGPT to create an extension for me. It looks like it’s done a good job but my knowledge of Wappler extension building is near zero so I would very much appreciate if someone with the knowledge (someone from the Wappler team?) could glance over it and let me know if this will do the job?

Hopefully I’ll be allowed to upload the zip file.

wappler-encrypt-upload-wrapper-full-helper.zip (3.7 KB)

This uses OpenSSL which I think most PHP-ready servers should have installed.

Although this is a NodeJS project, client side encryption part could help.

Hi Sid. Ooh, this looks very interesting. Do you think the client side code would be enough? I’m thinking the ideal solution is a form where the visitor can upload a file, the page encrypts it with the public before sending it to the server connect script. Then the option for staff to log in and download the file providing the private key in the browser so it can be opened but without ever sending the private key to the server.

Does your solution effectively provide this facility? Have you seen the other post I added today which has a solution to do this created by ChatGPT?

I haven’t created any Wappler extensions so am very newbie with this but if you’re able to glance over it and let me know if this should work then that would be great.

:slightly_smiling_face:

Happy to take a look, wont be until tomorrow though

1 Like

Wel, you only did half the job. Now get ChatGPT to analyse the package:

Complete Package Analysis

Current Structure :white_check_mark:

The extension is properly structured as a Wappler Server Connect module with:

  • :white_check_mark: Proper ext.json and package.json metadata
  • :white_check_mark: HJSON module definition for UI integration
  • :white_check_mark: PHP wrapper that calls the helper class
  • :white_check_mark: Separated library code in /lib
  • :white_check_mark: Clear input/output definitions

Issues & Improvements Needed

1. Server Connect Wrapper (encrypt_upload.php)

Current Issues:

  • No error handling
  • Direct access to $_FILES without validation
  • Missing proper Server Connect integration patterns
  • No output assignment to $this->setOutput()

2. Module Definition (encrypt_upload.hjson)

Improvements Needed:

  • Add default values for optional parameters
  • Add validation rules
  • Better output structure documentation
  • Add error output fields

3. Helper Class (EncryptUpload.php)

Issues Found:

  • No memory-efficient streaming for large files
  • Missing input validation
  • Weak error handling in file operations
  • Security: fallback to weaker PKCS1 padding
  • No configuration options
  • Missing file type/size validation

4. Documentation (README.md)

Missing:

  • Decryption instructions
  • Security best practices
  • Example usage in Server Connect
  • Key generation instructions

5. Extension Metadata

Suggestions:

  • Add icon/logo reference
  • Add repository/homepage URLs
  • Add dependencies check

Proposed Improvements

Would you like me to create improved versions of these files? Here's what I would enhance:

1. Enhanced EncryptUpload.php

  • Input validation and sanitization
  • Configurable options (max file size, allowed types, permissions)
  • Memory-efficient streaming for large files
  • Better error handling with error codes
  • Secure-only padding (no fallback)
  • Comprehensive PHPDoc
  • File type validation via MIME

2. Improved encrypt_upload.php wrapper

  • Proper Server Connect integration with $this->setOutput()
  • Error handling and validation
  • Access to Server Connect context
  • Proper data flow

3. Enhanced encrypt_upload.hjson

  • Validation rules on inputs
  • Default values
  • Better structured outputs with error codes
  • Additional optional configuration inputs

4. Expanded README

  • Complete usage examples
  • Key generation guide
  • Decryption example
  • Security best practices
  • Troubleshooting section

5. Additional Files

  • DecryptUpload.php - companion decryption class
  • Example Server Connect action JSON files
  • Security guidelines document

As an example, see what ChatGPT has done here
@benpley/wappler-html2pdf - npm

Yes. It has both server and client side capabilities to do so.

On the client side, I haven’t packaged it as Wappler extension, only on the backend.
I haven’t had the change to play with frontend extensions unfortunately.