.
3ss.cn

编写 Nginx 模块进行 RSA 加解密之完成基础计算部分

为了尽可能让文章简单,我将上面的代码进行了一定的精简和调整,只实现私钥加密的功能,并对外部使用的变量做了清理操作,减少了原始代码中内存溢出的问题,其他函数实现类似,在此就不多赘述。
考虑到 RSA 加密后的内容可读性不高,于是额外引入了一个简单的 Base64 编码实现。

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

char privateKey[] = "-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
                    "MIIJrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQICTqoISmC8M0CAggA\n"
                    ... ...
                    "onL8DKhku9s/5NB+eEVC3v4JubSfph0GEiVemMIQxMI2\n"
                    "-----END ENCRYPTED PRIVATE KEY-----\n";

char *passphrase = "soulteary.com";

int encrypt(unsigned char *data, int data_len, unsigned char *encrypted)
{
    BIO *keybio;
    keybio = BIO_new_mem_buf(privateKey, -1);

    RSA *rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, passphrase);
    int ret_len = RSA_private_encrypt(data_len, data, encrypted, rsa, RSA_PKCS1_PADDING);

    BIO_free(keybio);
    RSA_free(rsa);

    return ret_len;
}

char *base64(const unsigned char *input, int length)
{
    BIO *bmem, *b64;
    BUF_MEM *bptr;

    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);
    BIO_write(b64, input, length);
    BIO_flush(b64);
    BIO_get_mem_ptr(b64, &bptr);

    char *buff = (char *)malloc(bptr->length);
    memcpy(buff, bptr->data, bptr->length - 1);
    buff[bptr->length - 1] = 0;

    BIO_free_all(b64);

    return buff;
}

int main()
{

    char raw[2048 / 8] = "{\"key\": \"val\"}";
    unsigned char encrypted[4098] = {};

    int encrypted_length = encrypt(raw, strlen(raw), encrypted);
    if (encrypted_length == -1)
    {
        printf("Encrypt failed");
        exit(0);
    }

    char *result = base64(encrypted, encrypted_length);

    printf("%s\n", result);

    exit(0);
}

为了更方便的测试功能,将上面的内容保存为 encrypt.c,然后编写一个 Dockerfile 用于基础计算部分的编译测试(这里需要注意编译顺序,避免编译不通过):

FROM alpine:3.13 AS Builder

RUN cat /etc/apk/repositories | sed -e "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/" | tee /etc/apk/repositories
RUN apk add openssl-dev libressl-dev gcc g++
COPY ./encrypt.c /
RUN cd / && \
	gcc encrypt.c -lssl -lcrypto -o encrypt && \
	cp encrypt /bin/

使用 docker build -t test . 构建一个临时的容器,然后使用 docker run –rm -it test encrypt 测试程序,会得到类似下面的结果。

rFKPHoJPR4iExWgx6EFzLVA4uISNyxYDtmOlGT+e6SBy9SPDve4o5YNzSbX1grnj
bCFwvp80SwJzs1yaFzChDxo7HTdV3hK3syba+8zHw05FBeuw4/q8zn4e+KAv5QjE
KzrQvMlzE1XsPrbI+IjJpqGIrpy57VBVr8CpmT/RajqZ42fy/cgn429i3NJhlckW
vVPbY7x3vcXC/5FcRwR9hqPJ2qVXulVH/SxQ422bmLigFHwnWjT0qnDVTvgQFeQd
1edmJzPgbhycmGPvCdjRvN80eEX8lp3Oz92uACXfeReab26R0vhgGysPv3w97vdN
TPmt9l1eyeWSnYR/gWU9HSM7FbAJyvKLp5h07X4AYyf2uDl7DxWIJp+ZG/IxzCzt
2IzKN2siq2bqvJEqR7+wDS2ttgCzD2ogmMMiQFgAa1yDruRasSJbV408n7STmE6h
Z6klL8C+zXwgOLYnDi7bNVUhz6BkqHrt+utKql6zr0lKdOywwqElOQJeostBknH5
OCcoazuu+ZOOeAT3DoRLRVqHp/v75aIW9nYJmNjCqgonYrw9flKezh04nlSCjDaF
DYJKVUSsL0mAhGMxfcVWrEzWOTAIOvg6U3vshSpDKk3KCaRhamWxCMVItfBNeeHL
T8ZYF0tHz/cLkBm1wSNOuTxaGQRD/ZH0lSQGP8Aq4x4=

在验证完毕基础功能可行后,我们来看看怎么将它编写为一个 Nginx 可以调用的模块。

赞(0)
未经允许不得转载:互联学术 » 编写 Nginx 模块进行 RSA 加解密之完成基础计算部分

评论 抢沙发