RSA实现文件加密 c语言实现

本文原为 山东大学计算机系统原理实验二 的实现开源
鉴于计算机系统原理这个实验评分以加密算法难度为准,而加密算法显然不是计算机系统原理的重点,故开源我的实现以供其他同学参考。

实现分为两个源文件,keygen和cry,keygen负责生成密钥,cry负责加密解密。文末附完整代码。

keygen.c main部分

rsa算法原理不再阐述,它的密钥生成需要两个大素数p和q,以及一个与m互素的e,p,q越大安全性越高,这里附带一组p,q,e,可以改为输入形式,自己寻找大素数输入。
c语言实现高精度不好用(不引用第三方库),所以此处牺牲部分安全性换取高得多的编码便捷度。__int128范围达到1.7e38,38位精度勉强能当半个高精度用,注意部分编译器或机器不支持__int128,可以改为long long,然后减小p,q。

输出中(e,n)为公钥,(d,n)为私钥,是一对,公钥加密能且仅能以私钥解密,反之亦然。(一般的用法是公开公钥,其他人使用公钥加密文件发送,然后你收到后使用私钥解密)

int main()
{
    __int128 p = 179424673, q = 3262476787;
    //__int128 p = read(), q = read();
    __int128 n = p * q;
    __int128 m = (p - 1) * (q - 1);
    __int128 e = 1628441;
    //__int128 e = read();
    if (gcd(e, m) != 1)
    {
        printf("e is not coprime with m\n");
        return 0;
    }
    __int128 d;
    __int128 y;
    exgcd(e, m, d, y);
    d = (d % m + m) % m;
    printf("n= ");
    print(n);
    printf("\n");
    printf("e= ");
    print(e);
    printf("\n");
    printf("d= ");
    print(d);
    return 0;
}

cry.c main部分

同keygen,使用__int128代替高精度。
首先输入操作数,1加密2解密,然后要加(解)密的文件(注意附带后缀),以及密钥(e,n)或(d,n)
注意要解密的文件务必以.rsa为后缀,否则会删除后面四个字符(自行修改)

加密实现原理是把要加密的文件逐字节读取(char正好是一字节),然后逐字节加密,把每个字节加密为一段数字密文,输出到加密文件中,两字节间有空格方便解密时一个个密文读取。
解密就是把每个密文解密为一个字节然后输出到文件中。

int main()
{
    printf("input as following:\n1(encry) filename e n\n2(decry) filename d n\n");
    int ope;
    scanf("%d", &ope);
    char s[1000];
    scanf("%s", s);

    if (ope == 1)
    {
        __int128 e = read(), n = read();

        FILE *fp1 = freopen(s, "r", stdin);
        strcat(s, ".rsa");
        FILE *fp2 = freopen(s, "w", stdout);
        char c = getchar();
        while (c != EOF)
        {
            __int128 x = c;
            print(qpow(x, e, n));
            putchar(' ');
            c = getchar();
        }
        fclose(fp1);
        fclose(fp2);
    }
    else
    {
        __int128 d = read(), n = read();

        FILE *fp1 = freopen(s, "r", stdin);
        s[strlen(s) - 4] = '\0';
        FILE *fp2 = freopen(s, "w", stdout);
        __int128 x;
        while (x = read())
            printf("%c", (char)qpow(x, d, n));
        fclose(fp1);
        fclose(fp2);
    }
    return 0;
}

完整文件

cry.c

#include <stdio.h>
#include <string.h>

inline __int128 read()
{
    __int128 x = 0, f = 1;
    char ch;
    if ((ch = getchar()) == EOF)
        return 0;
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}

__int128 qpow(__int128 a, __int128 b, __int128 mod)
{
    __int128 ans = 1;
    while (b)
    {
        if (b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

int main()
{
    printf("input as following:\n1(encry) filename e n\n2(decry) filename d n\n");
    int ope;
    scanf("%d", &ope);
    char s[1000];
    scanf("%s", s);

    if (ope == 1)
    {
        __int128 e = read(), n = read();

        FILE *fp1 = freopen(s, "r", stdin);
        strcat(s, ".rsa");
        FILE *fp2 = freopen(s, "w", stdout);
        char c = getchar();
        while (c != EOF)
        {
            __int128 x = c;
            print(qpow(x, e, n));
            putchar(' ');
            c = getchar();
        }
        fclose(fp1);
        fclose(fp2);
    }
    else
    {
        __int128 d = read(), n = read();

        FILE *fp1 = freopen(s, "r", stdin);
        s[strlen(s) - 4] = '\0';
        FILE *fp2 = freopen(s, "w", stdout);
        __int128 x;
        while (x = read())
            printf("%c", (char)qpow(x, d, n));
        fclose(fp1);
        fclose(fp2);
    }
    return 0;
}

keygen.c

#include <stdio.h>
#include <string.h>
inline __int128 read()
{
    __int128 x = 0, f = 1;
    char ch;
    if ((ch = getchar()) == EOF)
        return 0;
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}

__int128 qpow(__int128 a, __int128 b, __int128 mod)
{
    __int128 ans = 1;
    while (b)
    {
        if (b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

__int128 exgcd(__int128 a, __int128 b, __int128 &x, __int128 &y)
{
    if (!b)
    {
        x = 1;
        y = 0;
        return a;
    }
    __int128 d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

__int128 gcd(__int128 a, __int128 b)
{
    return b ? gcd(b, a % b) : a;
}

int main()
{
    __int128 p = 179424673, q = 3262476787;
    //__int128 p = read(), q = read();
    __int128 n = p * q;
    __int128 m = (p - 1) * (q - 1);
    __int128 e = 1628441;
    //__int128 e = read();
    if (gcd(e, m) != 1)
    {
        printf("e is not coprime with m\n");
        return 0;
    }
    __int128 d;
    __int128 y;
    exgcd(e, m, d, y);
    d = (d % m + m) % m;
    printf("n= ");
    print(n);
    printf("\n");
    printf("e= ");
    print(e);
    printf("\n");
    printf("d= ");
    print(d);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值