RSA + AES Double Layer Encryption/Decryption in Go

Diagram Breakdown:

  1. User: Initiates the process, including key generation and data encryption.
  2. RSA Keys: Public and private RSA keys are generated.
  3. AES Key: AES key is generated for encryption.
  4. Data: The message or data that needs to be encrypted.
  5. AES Encryption/Decryption: Represents the AES encryption and decryption steps.
  6. RSA Encryption/Decryption: Represents the RSA encryption and decryption steps.

Flow:

  • Encryption:
    1. AES Encryption: The user encrypts the data using the AES key.
    2. RSA Encryption: The AES-encrypted data is then encrypted using the RSA public key.
  • Decryption:
    1. RSA Decryption: The RSA-encrypted data is decrypted using the RSA private key.
    2. AES Decryption: The RSA-decrypted data is then decrypted using the AES key.

This diagram will give a visual representation of how the double-layer encryption and decryption process works with RSA and AES.


Here's how you can implement RSA + AES double-layer encryption and decryption in Go:

Dependencies:

You can use the crypto package for RSA and AES in Go. No need for external dependencies.

Step 1: Import Required Packages

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"io"
)

Step 2: RSA Key Generation Functions

// Generate RSA Keys
func generateRSAKeys(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
	privKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return nil, nil, err
	}
	return privKey, &privKey.PublicKey, nil
}

// RSA Encryption
func rsaEncrypt(publicKey *rsa.PublicKey, data []byte) ([]byte, error) {
	return rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, data, nil)
}

// RSA Decryption
func rsaDecrypt(privateKey *rsa.PrivateKey, encryptedData []byte) ([]byte, error) {
	return rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedData, nil)
}

Step 3: AES Key Generation and Encryption/Decryption Functions

// Generate AES Key
func generateAESKey() ([]byte, error) {
	key := make([]byte, 32) // 256-bit key
	_, err := rand.Read(key)
	if err != nil {
		return nil, err
	}
	return key, nil
}

// AES Encryption
func aesEncrypt(key, data []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}

	// Generate a random IV
	iv := make([]byte, aes.BlockSize)
	if _, err := rand.Read(iv); err != nil {
		return "", err
	}

	stream := cipher.NewCTR(block, iv)
	encrypted := make([]byte, len(data))
	stream.XORKeyStream(encrypted, data)

	// Combine IV and encrypted data (IV first)
	encryptedData := append(iv, encrypted...)
	return base64.StdEncoding.EncodeToString(encryptedData), nil
}

// AES Decryption
func aesDecrypt(key []byte, encryptedData string) ([]byte, error) {
	data, err := base64.StdEncoding.DecodeString(encryptedData)
	if err != nil {
		return nil, err
	}

	// Extract IV and encrypted data
	iv := data[:aes.BlockSize]
	encrypted := data[aes.BlockSize:]

	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	stream := cipher.NewCTR(block, iv)
	decrypted := make([]byte, len(encrypted))
	stream.XORKeyStream(decrypted, encrypted)

	return decrypted, nil
}

Step 4: Combine RSA + AES for Double-Layer Encryption/Decryption

// Encrypt data with RSA + AES
func encryptDataWithDoubleLayer(data string, publicKey *rsa.PublicKey, aesKey []byte) (string, error) {
	// First layer: AES Encryption
	aesEncryptedData, err := aesEncrypt(aesKey, []byte(data))
	if err != nil {
		return "", err
	}

	// Second layer: RSA Encryption of AES-encrypted data
	rsaEncryptedData, err := rsaEncrypt(publicKey, []byte(aesEncryptedData))
	if err != nil {
		return "", err
	}

	// Return RSA encrypted data as base64 string
	return base64.StdEncoding.EncodeToString(rsaEncryptedData), nil
}

// Decrypt data with RSA + AES
func decryptDataWithDoubleLayer(encryptedData string, privateKey *rsa.PrivateKey, aesKey []byte) (string, error) {
	// First layer: RSA Decryption
	rsaDecryptedData, err := base64.StdEncoding.DecodeString(encryptedData)
	if err != nil {
		return "", err
	}

	decryptedData, err := rsaDecrypt(privateKey, rsaDecryptedData)
	if err != nil {
		return "", err
	}

	// Second layer: AES Decryption of RSA-decrypted data
	aesDecryptedData, err := aesDecrypt(aesKey, string(decryptedData))
	if err != nil {
		return "", err
	}

	return string(aesDecryptedData), nil
}

Step 5: Example Usage

func main() {
	// Generate RSA keys
	privKey, pubKey, err := generateRSAKeys(2048)
	if err != nil {
		fmt.Println("Error generating RSA keys:", err)
		return
	}

	// Generate AES key
	aesKey, err := generateAESKey()
	if err != nil {
		fmt.Println("Error generating AES key:", err)
		return
	}

	// Data to be encrypted
	data := "This is a secret message"

	// Encrypt data with double-layer encryption (RSA + AES)
	encryptedData, err := encryptDataWithDoubleLayer(data, pubKey, aesKey)
	if err != nil {
		fmt.Println("Error encrypting data:", err)
		return
	}
	fmt.Println("Encrypted Data:", encryptedData)

	// Decrypt the data with double-layer decryption (RSA + AES)
	decryptedData, err := decryptDataWithDoubleLayer(encryptedData, privKey, aesKey)
	if err != nil {
		fmt.Println("Error decrypting data:", err)
		return
	}
	fmt.Println("Decrypted Data:", decryptedData)
}

Explanation:

  1. RSA Key Generation: Generates RSA public and private keys.
  2. AES Key Generation: Generates a 256-bit AES key.
  3. AES Encryption/Decryption: Uses AES-CTR mode for encryption and decryption of data.
  4. RSA Encryption/Decryption: Encrypts the AES-encrypted data using RSA and vice versa.
  5. Double-Layer Encryption: First, the data is encrypted with AES, then the AES-encrypted data is encrypted with RSA.

Key Steps:

  1. Encryption:
    • Data is first encrypted using AES.
    • The AES-encrypted data is then encrypted using RSA.
  2. Decryption:
    • The RSA-encrypted data is decrypted first.
    • The resulting data is then decrypted using the AES key.

This Go implementation provides robust double-layer encryption using both RSA and AES

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete