源程序来自Gethub的Simple implementation of the RSA algorithm。

程序中有关类型转换代码略做修改,并且已经能够编译运行。

程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>#define ACCURACY 5
#define SINGLE_MAX 10000
#define EXPONENT_MAX 1000
#define BUF_SIZE 1024/*** Computes a^b mod c*/
int modpow(long long a, long long b, int c) {int res = 1;while(b > 0) {/* Need long multiplication else this will overflow... */if(b & 1) {res = (res * a) % c;}b = b >> 1;a = (a * a) % c; /* Same deal here */}return res;
}/*** Computes the Jacobi symbol, (a, n)*/
int jacobi(int a, int n) {int twos, temp;int mult = 1;while(a > 1 && a != n) {a = a % n;if(a <= 1 || a == n) break;twos = 0;while(a % 2 == 0 && ++twos) a /= 2; /* Factor out multiples of 2 */if(twos > 0 && twos % 2 == 1) mult *= (n % 8 == 1 || n % 8 == 7) * 2 - 1;if(a <= 1 || a == n) break;if(n % 4 != 1 && a % 4 != 1) mult *= -1; /* Coefficient for flipping */temp = a;a = n;n = temp;}if(a == 0) return 0;else if(a == 1) return mult;else return 0; /* a == n => gcd(a, n) != 1 */
}/*** Check whether a is a Euler witness for n*/
int solovayPrime(int a, int n) {int x = jacobi(a, n);if(x == -1) x = n - 1;return x != 0 && modpow(a, (n - 1)/2, n) == x;
}/*** Test if n is probably prime, using accuracy of k (k solovay tests)*/
int probablePrime(int n, int k) {if(n == 2) return 1;else if(n % 2 == 0 || n == 1) return 0;while(k-- > 0) {if(!solovayPrime(rand() % (n - 2) + 2, n)) return 0;}return 1;
}/*** Find a random (probable) prime between 3 and n - 1, this distribution is* nowhere near uniform, see prime gaps*/
int randPrime(int n) {int prime = rand() % n;n += n % 2; /* n needs to be even so modulo wrapping preserves oddness */prime += 1 - prime % 2;while(1) {if(probablePrime(prime, ACCURACY)) return prime;prime = (prime + 2) % n;}
}/*** Compute gcd(a, b)*/
int gcd(int a, int b) {int temp;while(b != 0) {temp = b;b = a % b;a = temp;}return a;
}/*** Find a random exponent x between 3 and n - 1 such that gcd(x, phi) = 1,* this distribution is similarly nowhere near uniform*/
int randExponent(int phi, int n) {int e = rand() % n;while(1) {if(gcd(e, phi) == 1) return e;e = (e + 1) % n;if(e <= 2) e = 3;}
}/*** Compute n^-1 mod m by extended euclidian method*/
int inverse(int n, int modulus) {int a = n, b = modulus;int x = 0, y = 1, x0 = 1, y0 = 0, q, temp;while(b != 0) {q = a / b;temp = a % b;a = b;b = temp;temp = x; x = x0 - q * x; x0 = temp;temp = y; y = y0 - q * y; y0 = temp;}if(x0 < 0) x0 += modulus;return x0;
}/*** Read the file fd into an array of bytes ready for encryption.* The array will be padded with zeros until it divides the number of* bytes encrypted per block. Returns the number of bytes read.*/
int readFile(FILE* fd, char** buffer, int bytes) {int len = 0, cap = BUF_SIZE, r;char buf[BUF_SIZE];*buffer = (char *)malloc(BUF_SIZE * sizeof(char));while((r = fread(buf, sizeof(char), BUF_SIZE, fd)) > 0) {if(len + r >= cap) {cap *= 2;*buffer = (char *)realloc(*buffer, cap);}memcpy(&(*buffer)[len], buf, r);len += r;}/* Pad the last block with zeros to signal end of cryptogram. An additional block is added if there is no room */if(len + bytes - len % bytes > cap) *buffer = (char *)realloc(*buffer, len + bytes - len % bytes);do {(*buffer)[len] = '\0';len++;}while(len % bytes != 0);return len;
}/*** Encode the message m using public exponent and modulus, c = m^e mod n*/
int encode(int m, int e, int n) {return modpow(m, e, n);
}/*** Decode cryptogram c using private exponent and public modulus, m = c^d mod n*/
int decode(int c, int d, int n) {return modpow(c, d, n);
}/*** Encode the message of given length, using the public key (exponent, modulus)* The resulting array will be of size len/bytes, each index being the encryption* of "bytes" consecutive characters, given by m = (m1 + m2*128 + m3*128^2 + ..),* encoded = m^exponent mod modulus*/
int* encodeMessage(int len, int bytes, char* message, int exponent, int modulus) {int *encoded = (int *)malloc((len/bytes) * sizeof(int));int x, i, j;for(i = 0; i < len; i += bytes) {x = 0;for(j = 0; j < bytes; j++) x += message[i + j] * (1 << (7 * j));encoded[i/bytes] = encode(x, exponent, modulus);
#ifndef MEASUREprintf("%d ", encoded[i/bytes]);
#endif}return encoded;
}/*** Decode the cryptogram of given length, using the private key (exponent, modulus)* Each encrypted packet should represent "bytes" characters as per encodeMessage.* The returned message will be of size len * bytes.*/
int* decodeMessage(int len, int bytes, int* cryptogram, int exponent, int modulus) {int *decoded = (int *)malloc(len * bytes * sizeof(int));int x, i, j;for(i = 0; i < len; i++) {x = decode(cryptogram[i], exponent, modulus);for(j = 0; j < bytes; j++) {decoded[i*bytes + j] = (x >> (7 * j)) % 128;
#ifndef MEASUREif(decoded[i*bytes + j] != '\0') printf("%c", decoded[i*bytes + j]);
#endif}}return decoded;
}/*** Main method to demostrate the system. Sets up primes p, q, and proceeds to encode and* decode the message given in "text.txt"*/
int main(void) {int p, q, n, phi, e, d, bytes, len;int *encoded, *decoded;char *buffer;FILE *f;srand(time(NULL));while(1) {p = randPrime(SINGLE_MAX);printf("Got first prime factor, p = %d ... ", p);getchar();q = randPrime(SINGLE_MAX);printf("Got second prime factor, q = %d ... ", q);getchar();n = p * q;printf("Got modulus, n = pq = %d ... ", n);if(n < 128) {printf("Modulus is less than 128, cannot encode single bytes. Trying again ... ");getchar();}else break;}if(n >> 21) bytes = 3;else if(n >> 14) bytes = 2;else bytes = 1;getchar();phi = (p - 1) * (q - 1);printf("Got totient, phi = %d ... ", phi);getchar();e = randExponent(phi, EXPONENT_MAX);printf("Chose public exponent, e = %d\nPublic key is (%d, %d) ... ", e, e, n);getchar();d = inverse(e, phi);printf("Calculated private exponent, d = %d\nPrivate key is (%d, %d) ... ", d, d, n);getchar();printf("Opening file \"text.txt\" for reading\n");f = fopen("text.txt", "r");if(f == NULL) {printf("Failed to open file \"text.txt\". Does it exist?\n");return EXIT_FAILURE;}len = readFile(f, &buffer, bytes); /* len will be a multiple of bytes, to send whole chunks */fclose(f);printf("File \"text.txt\" read successfully, %d bytes read. Encoding byte stream in chunks of %d bytes ... ", len, bytes);getchar();encoded = encodeMessage(len, bytes, buffer, e, n);printf("\nEncoding finished successfully ... ");getchar();printf("Decoding encoded message ... ");getchar();decoded = decodeMessage(len/bytes, bytes, encoded, d, n);printf("\nFinished RSA demonstration!\n");free(encoded);free(decoded);free(buffer);return EXIT_SUCCESS;
}

转载于:https://www.cnblogs.com/tigerisland/p/7564843.html

C语言实现的RSA算法程序相关推荐

  1. C语言实现的RSA算法程序(使用GMP)

    这个程序使用了GMP包,所以程序比较简洁,并且几乎不论多大的整数都可以计算. 代码来自rosettacode.org的RSA code. C语言程序如下: #include <stdio.h&g ...

  2. 跨语言平台的RSA加密、解密、签名、验证算法的实现

      在网上可以找到各种各样的RSA实现代码,原理都是RSA算法的基本原理,但是在处理数据块划分.填充等问题上都是形形色色的,本文旨在探讨.实现遵循RFC 2313 PKCS#1 v1.5标准的一种跨语 ...

  3. 芯片验证学perl还是python_科学网—用python或perl语言简单验证RSA算法 - 康建的博文...

    python或perl语言都提供了很方便的对大整数计算的功能,这在C或Fortran中不易实现,需调用相关的库或另编程序. 多年前听公开课,一位老师给学生讲电子商务安全,涉及到公钥密码,讲得生动,但没 ...

  4. openssl在多平台和多语言之间进行RSA加解密注意事项

    首先说一下平台和语言: 系统平台为CentOS6.3,RSA加解密时使用NOPADDING进行填充 1)使用C/C++调用系统自带的openssl 2)Android4.2模拟器,第三方openssl ...

  5. 一个简单地C语言程序展示RSA加密原理

    #include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h>//质数判定 ...

  6. c语言实现rsa签名验证,C语言openssl库RSA签名

    1.源码实现 #include #include #include #include #include //公钥验证签名 int my_verify(const char *input, int in ...

  7. rsa算法程序代码php,C++ 实现 RSA算法

    一. RSA算法 RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大 ...

  8. c语言Mbedtls实现rsa加解密(公私钥以文件或者字符串的读取的方式实现)(亲测可用)

    效果: Encrypted: B5 D2 07 92 8D 7B C2 4C 94 51 8F 02 82 02 58 3A 48 A8 2B 6B 65 4F A1 46 5C D8 21 11 0 ...

  9. 用c语言实现蚂蚁算法,rsa算法的c语言实现

    rsa算法的c语言实现 RSA 算法的 C 语言实现一.RSA 算法的描述 1.选取长度相等的两个大素数 p 和 q,计算其乘积: n=pq 然后随机选取加密密钥 e,使 e 和 (p–1)(q–1) ...

最新文章

  1. 从零开始学习 ASP.NET MVC 1.0 (三) Controller/Action 深入解析与应用实例 【转】
  2. 花生问题——百练OJ:2950:摘花生与1928:The Peanuts
  3. 异常与锁的释放(synchronized )
  4. Linux系列-Red Hat5平台下的Postfix邮件服务搭建(二)
  5. Linux下解压缩包命令
  6. 金融数据分析与挖掘实战练习2.10
  7. 第六章 线程的基础知识
  8. Egret入门学习日记 --- 第十七篇(书中 7.4~8.2节 内容)
  9. Android攻略--单位转化器UC--Units Converter(学习笔记)
  10. LCD(六)显示控制器、framebuffer驱动、s3c-fb.c中probe函数分析
  11. android gps开发必备资料(含测试demo下载)
  12. python 大数据入门教程
  13. java 数字转大写_数字转大写(java)
  14. BZOJ3110 K大数查询
  15. 【PHPWord】解决Word转PDF可能出现的空白页问题 | 插入换行符、分页符、定义文档网络时对齐网格
  16. 一个基于QT的解析interproscan结果的C++成员函数
  17. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——2.8 小结...
  18. mysql - database/数据库
  19. java jackson包_jackson.jar
  20. 工作5年的阿里Java程序员分享从业心得总结,写给还在迷茫的朋友

热门文章

  1. 求生2本地服务器怎么修改参数,《求生之路2》服务器指令及难度参数设置(难度篇).pdf...
  2. php 数组的处理,php 数组处理
  3. ubuntu 无法启动mysql_解决ubuntu下安装mysql使用service 无法启动问题
  4. 本行没有输入值结余隐藏_仓库库存管理系统,内含逻辑公式,自动结余库存!操作简单易上手...
  5. python代码运行到一半终止_Python 程序运行时卡住,既不报错,也不停止,也不动,是什么原因?...
  6. 计算机中汉字用什么表示什么,在计算机中汉字是用几个字节表示
  7. 三位数的茎叶图怎么看_人参怎么判断年份,这些点你要了解
  8. 计算机调剂名额多的考研学校,避免调剂被刷,2020年考研调剂最容易成功的4类院校,提前了解!...
  9. 2018年计算机应用基础性考,2018年电大计算机应用基础核心课形考册
  10. 大数据学习笔记27:MR案例——多输入源处理成绩