Here is my code(I am including -lsodium when compiling:
#include <sodium.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
// Preprocessor directives
#define KEY_SIZE 32
#define NONCE_SIZE 8
#define INPUT_SIZE 128
bool is_valid_email(const char *email) {
const char *at_ptr = strchr(email, '@');
if (at_ptr == NULL || at_ptr == email || at_ptr[1] == '\0') {
return false;
}
const char *dot_ptr = strrchr(at_ptr, '.');
if (dot_ptr == NULL || dot_ptr == (at_ptr + 1) || dot_ptr[1] == '\0') {
return false;
}
return true;
}
bool is_valid_password(const char *password) {
int len = strlen(password);
if (len < 12) {
return false;
}
bool has_digit = false;
bool has_upper = false;
bool has_special = false;
for (int i = 0; i < len; ++i) {
if (isdigit(password[i])) {
has_digit = true;
} else if (isupper(password[i])) {
has_upper = true;
} else if (strchr("!?(),", password[i]) != NULL) {
has_special = true;
}
}
return has_digit && has_upper && has_special;
}
bool is_valid_ipv4(const char *ipv4) {
int octets[4];
char extra;
if (sscanf(ipv4, "%d.%d.%d.%d%c", &octets[0], &octets[1], &octets[2], &octets[3], &extra) != 4) {
return false;
}
for (int i = 0; i < 4; ++i) {
if (octets[i] < 0 || octets[i] > 255) {
return false;
}
}
return true;
}
void encrypt(const char *input, unsigned char *ciphertext, unsigned char *key, unsigned char *nonce, size_t input_len) {
// Generate random key and nonce
randombytes_buf(key, KEY_SIZE);
randombytes_buf(nonce, NONCE_SIZE);
// Encrypt the input fields
crypto_stream_salsa20_xor(ciphertext, (const unsigned char *)input, input_len, nonce, key);
}
void decrypt(unsigned char *plaintext, unsigned char *ciphertext, size_t len, unsigned char *key, unsigned char *nonce) {
// Decrypt the data
crypto_stream_salsa20_xor(plaintext, ciphertext, len, nonce, key);
}
int main() {
// Initialize libsodium
if (sodium_init() < 0) {
printf("The necessary libraries are not available, exiting\n");
return 1;
}
// Prompt user for mode selection (encrypt/decrypt)
char mode[INPUT_SIZE];
printf("Enter mode (encrypt/decrypt): ");
fgets(mode, INPUT_SIZE, stdin);
// If user chooses to encrypt
if (strncmp(mode, "encrypt\n", INPUT_SIZE) == 0) {
char field1[INPUT_SIZE];
char field2[INPUT_SIZE];
char field3[INPUT_SIZE];
// Prompt user for input fields and validate them
do {
printf("Enter email: ");
fgets(field1, INPUT_SIZE, stdin);
field1[strcspn(field1, "\n")] = 0;
} while (!is_valid_email(field1));
do {
printf("Enter password (min 12 characters, at least one uppercase, one digit, and one special character !?(),): ");
fgets(field2, INPUT_SIZE, stdin);
field2[strcspn(field2, "\n")] = 0;
} while (!is_valid_password(field2));
do {
printf("Enter IPv4 address: ");
fgets(field3, INPUT_SIZE, stdin);
field3[strcspn(field3, "\n")] = 0;
} while (!is_valid_ipv4(field3));
// Encrypt the input fields
unsigned char key1[KEY_SIZE], key2[KEY_SIZE], key3[KEY_SIZE];
unsigned char nonce1[NONCE_SIZE], nonce2[NONCE_SIZE], nonce3[NONCE_SIZE];
unsigned char encrypted1[INPUT_SIZE];
unsigned char encrypted2[INPUT_SIZE];
unsigned char encrypted3[INPUT_SIZE];
encrypt(field1, encrypted1, key1, nonce1, strlen(field1));
encrypt(field2, encrypted2, key2, nonce2, strlen(field2));
encrypt(field3, encrypted3, key3, nonce3, strlen(field3));
// Write the encrypted data, key, and nonce to a file
FILE *file = fopen("encrypted_data.bin", "wb");
if (file == NULL) {
printf("Error: Unable to open file\n");
return 1;
}
fwrite(key1, 1, KEY_SIZE, file);
fwrite(nonce1, 1, NONCE_SIZE, file);
fwrite(key2, 1, KEY_SIZE, file);
fwrite(nonce2, 1, NONCE_SIZE, file);
fwrite(key3, 1, KEY_SIZE, file);
fwrite(nonce3, 1, NONCE_SIZE, file);
fclose(file);
printf("Encryption successful. Data saved to encrypted_data.bin\n");
}
else if (strncmp(mode, "decrypt\n", INPUT_SIZE) == 0) {
// Read encrypted data, key, and nonce from the file
FILE *file = fopen("encrypted_data.bin", "rb");
if (file == NULL) {
printf("Error: Unable to open file\n");
return 1;
}
unsigned char encrypted1[INPUT_SIZE];
unsigned char encrypted2[INPUT_SIZE];
unsigned char encrypted3[INPUT_SIZE];
unsigned char key1[KEY_SIZE];
unsigned char nonce1[NONCE_SIZE];
unsigned char key2[KEY_SIZE];
unsigned char nonce2[NONCE_SIZE];
unsigned char key3[KEY_SIZE];
unsigned char nonce3[NONCE_SIZE];
fread(encrypted1, 1, INPUT_SIZE, file);
fread(encrypted2, 1, INPUT_SIZE, file);
fread(encrypted3, 1, INPUT_SIZE, file);
fread(key1, 1, KEY_SIZE, file);
fread(nonce1, 1, NONCE_SIZE, file);
fread(key2, 1, KEY_SIZE, file);
fread(nonce2, 1, NONCE_SIZE, file);
fread(key3, 1, KEY_SIZE, file);
fread(nonce3, 1, NONCE_SIZE, file);
fclose(file);
// Decrypt the data
unsigned char decrypted1[INPUT_SIZE];
unsigned char decrypted2[INPUT_SIZE];
unsigned char decrypted3[INPUT_SIZE];
decrypt(decrypted1, encrypted1, INPUT_SIZE, key1, nonce1);
decrypt(decrypted2, encrypted2, INPUT_SIZE, key2, nonce2);
decrypt(decrypted3, encrypted3, INPUT_SIZE, key3, nonce3);
// Display the decrypted data
printf("Decrypted email: %s\n", decrypted1);
printf("Decrypted password: %s\n", decrypted2);
printf("Decrypted IPv4 address: %s\n", decrypted3);
}
else {
printf("Invalid choice. Please enter 'encrypt' or 'decrypt'.\n");
}
return 0;
}
and the outputted return:
Decrypted email: ��������AN����L��ϑ)��,��j��?О\>7�Y�n���c���"�H�T��C�:�:���0�2q\`%h��\]"WRz��& Ҟ���FUC}���dc-��5��:\>�4{���Kh�:.���iu���ŷ*�-\[
Decrypted password: h�:.���iu���ŷ*�-\[
Decrypted IPv4 address: ϊgo��x�r%�kg�3Y�AYԡ����!�5
���C�l\~}\<\]uL����H͈bڧ��#P�2 �F��lu�����5 �
���1K|%�\*E����ҫ�1|�k6�H ���s\~x\_�
�L�x�
I tried to encrypt and decrypt, however the decrypt is not working as intended.