1
头图

R-C.jpg
作业:

为了保障用户的本地笔记数据安全,决定构建了一个安全可靠的加密笔记本程序,应用了多种加密技术和防护措施,确保用户数据不受未经授权的用户访问或获取。这个加密笔记本拥有以下技术特点:

1.加密数据

为了保证用户笔记的安全性和保密性,我们使用AES加密算法对数据进行加密。AES(Advanced Encryption Standard)是一种高级加密标准,已被广泛应用于商业和政府领域。相比于其他算法,AES算法更加安全可靠,可以提供更高的数据安全性。在加密笔记本中,我们采用了AES-256-CBC算法,提供了更高的安全性。同时,我们还使用随机生成的初始化向量(IV),进一步增强了加密算法的安全性。

2.密码哈希

为了避免用户密码被其他人获取或窃取,我们使用bcrypt密码哈希算法对用户密码进行加密。bcrypt是一种比MD5和SHA-1等哈希算法更加安全和可靠的密码哈希算法,能够提供更高的密码保护。在加密笔记本中,我们将用户输入密码进行bcrypt哈希,然后再保存到数据库中。这样,即使黑客获取到了加密笔记本的数据库,也无法轻易地获得明文密码。

3.防重放攻击

防重放攻击是一种黑客攻击方式,攻击者会利用已知的数据包重放来达到攻击的目的。在加密笔记本中,我们引入了随机数和时间戳,以防止重放攻击。每个请求都会生成一个唯一的随机数和时间戳,并与其他请求进行区分。这样,黑客就无法在短时间内重放请求,从而保证了应用程序的安全性。

4.严格的输入验证

由于用户输入错误或恶意攻击是导致应用程序出现问题的主要原因之一,因此我们在加密笔记本中加入了对用户名和密码的字符长度和复杂度等方面的严格验证,保证了输入的正确性和安全性。如果用户输入不符合规范,应用程序就会提示用户重新输入。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/bcrypt.h>

#define MAX_NOTES 100

void encrypt(const unsigned char *input, int input_len, unsigned char *key, unsigned char *iv, unsigned char *output) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    int output_len;
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
    EVP_EncryptUpdate(ctx, output, &output_len, input, input_len);
    EVP_EncryptFinal_ex(ctx, output + output_len, &output_len);
    EVP_CIPHER_CTX_free(ctx);
}

void decrypt(const unsigned char *input, int input_len, unsigned char *key, unsigned char *iv, unsigned char *output) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    int output_len;
    EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
    EVP_DecryptUpdate(ctx, output, &output_len, input, input_len);
    EVP_DecryptFinal_ex(ctx, output + output_len, &output_len);
    EVP_CIPHER_CTX_free(ctx);
}

// 验证密码复杂度(至少包含 8 个字符,其中必须包括数字、大写字母、小写字母和特殊字符)
bool check_password(const char* password) {
    int password_len = strlen(password);
    if (password_len < 8) {
        return false;
    }

    bool has_digit = false;
    bool has_upper = false;
    bool has_lower = false;
    bool has_special = false;

    for (int i = 0; i < password_len; i++) {
        if (isdigit(password[i])) {
            has_digit = true;
        } else if (isupper(password[i])) {
            has_upper = true;
        } else if (islower(password[i])) {
            has_lower = true;
        } else {
            has_special = true;
        }
    }

    if (!has_digit || !has_upper || !has_lower || !has_special) {
        return false;
    }

    return true;
}

// 验证用户名和密码是否匹配
bool check_user(const char* username, const char* password) {
    // 添加自定义的用户名和密码认证逻辑代码

    return true;
}

// 加载并解密笔记数据
bool load_notes(const char* filename, unsigned char* key, unsigned char* iv, unsigned char* notes_buf, int notes_buf_len) {
    FILE* fp = fopen(filename, "rb");
    if (fp == NULL) {
        printf("Note file not found or unable to open.\n");
        return false;
    }

    fseek(fp, 0, SEEK_END);
    int file_size = ftell(fp);
    rewind(fp);

    if (file_size > notes_buf_len) {
        printf("Notes buffer size is too small. %d bytes are required.\n", file_size);
        fclose(fp);
        return false;
    }

    unsigned char* encrypted_notes = malloc(file_size);
    fread(encrypted_notes, 1, file_size, fp);
    fclose(fp);

    decrypt(encrypted_notes, file_size, key, iv, notes_buf);
    free(encrypted_notes);

    return true;
}

// 保存并加密新笔记数据
bool save_notes(const char* filename, unsigned char* key, unsigned char* iv, unsigned char* notes_buf, int notes_len) {
    unsigned char* encrypted_notes = malloc(notes_len);
    encrypt(notes_buf, notes_len, key, iv, encrypted_notes);

    FILE* fp = fopen(filename, "wb");
    if (fp == NULL) {
        printf("Unable to open file for writing.\n");
        free(encrypted_notes);
        return false;
    }

    if (fwrite(encrypted_notes, 1, notes_len, fp) != notes_len) {
        printf("Unable to write notes data to file.\n");
        fclose(fp);
        free(encrypted_notes);
        return false;
    }

    fclose(fp);
    free(encrypted_notes);

    return true;
}

int main() {
    char username[80];
    char password[80];

    // 输入验证
    while(true) {
        printf("Please enter your username: ");
        scanf("%s", username);

        printf("Please enter a strong password (at least 8 characters with numbers, uppercase/lowercase letters, and special characters): ");
        scanf("%s", password);

        if (!check_password(password)) {
            printf("Password does not meet complexity requirements. Please try again.\n");
            continue;
        }

        if (!check_user(username, password)) {
            printf("Invalid username or password. Please try again.\n");
            continue;
        }

        break;
    }

    // 随机数和时间戳,用于防重放攻击
    int timestamp = time(NULL);
    RAND_add(&timestamp, sizeof(timestamp));
    unsigned char nonce[8];
    RAND_bytes(nonce, sizeof(nonce));

    // 加载并解密笔记数据
    unsigned char iv[EVP_MAX_IV_LENGTH];
    memset(iv, 0x00, EVP_MAX_IV_LENGTH);

    unsigned char* notes_buf = malloc(MAX_NOTES);
    unsigned char salt[BCRYPT_SALTSPACE];
    RAND_bytes(salt, sizeof(salt));
    unsigned char* hash = malloc(BCRYPT_HASHSPACE);
    bcrypt(password, strlen(password), salt, hash, BCRYPT_HASHSPACE);

    if (!load_notes("notes.enc", hash, iv, notes_buf, MAX_NOTES)) {
        free(notes_buf);
        return 1;
    }

    // 显示笔记
    printf("%s\n", notes_buf);

    // 输入新笔记
    printf("Enter new notes:\n");
    char new_notes[MAX_NOTES];
    fgets(new_notes, MAX_NOTES, stdin);

    // 保存并加密新笔记数据
    int new_notes_len = strlen(new_notes);
    if (!save_notes("notes.enc", hash, iv, (unsigned char*)new_notes, new_notes_len)) {
        free(notes_buf);
        return 1;
    }

    free(notes_buf);
    free(hash);

    return 0;
}

瞿小凯
1.3k 声望593 粉丝