SEED Labs – RSA Public-Key Encryption and Signature Lab

目录

Task 1: Deriving the Private Key

Task 2: Encrypting a Message

Task 3: Decrypting a Message

Task 4: Signing a Message

Task 5: Verifying a Signature

Task 6: Manually Verifying an X.509 Certificate

             Step 1: Download a certificate from a real web server.

             Step 2: Extract the public key (e, n) from the issuer’s certificate.

             Step 3: Extract the signature from the server’s certificate.             

             Step 4: Extract the body of the server’s certificate.

             Step 5: Verify the signature.


测试示例

gcc bn_sample.c -lcrypto

Task 1: Deriving the Private Key

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *p = BN_new();
  BIGNUM *q = BN_new();
  BIGNUM *n = BN_new();
  BIGNUM *p_ = BN_new();
  BIGNUM *q_ = BN_new();
  BIGNUM *n_ = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *d = BN_new();
  
  BN_hex2bn(&p, "F7E75FDC469067FFDC4E847C51F452DF");
  BN_hex2bn(&q, "E85CED54AF57E53E092113E62F436F4F");
  BN_hex2bn(&e, "0D88C3");
  
  BN_sub(p_, p, BN_value_one()); //p-1
  BN_sub(q_, q, BN_value_one()); //q-1
  BN_mul(n, p, q, ctx); //n
  BN_mul(n_, p_, q_, ctx); //φ(n)
  BN_mod_inverse(d, e, n_, ctx); //ed mod φ(n)=1
  
  
  printBN("p = ", p);
  printBN("q = ", q);
  printBN("e = ", e);
  printBN("n = ", n);
  printBN("d = ", d);
  return 0;
}

Task 2: Encrypting a Message

其需要加密的十六进制串为4120746f702073656372657421

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *n = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *m = BN_new();
  BIGNUM *c = BN_new();
  
  BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
  BN_hex2bn(&e, "010001");
  BN_hex2bn(&m, "4120746f702073656372657421");
  
  BN_mod_exp(c, m, e, n, ctx); //c=m^e mod n
  
  printBN("c = ", c);
  return 0;
}

Task 3: Decrypting a Message

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *n = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *d = BN_new();
  BIGNUM *m = BN_new();
  BIGNUM *c = BN_new();
  
  BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
  BN_hex2bn(&e, "010001");
  BN_hex2bn(&d, "74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D");
  BN_hex2bn(&c, "6FB078DA550B2650832661E14F4F8D2CFAEF475A0DF3A75CACDC5DE5CFC5FADC");
  
  BN_mod_exp(m, c, d, n, ctx); //m=c^d mod n
  
  printBN("m = ", m);
  return 0;
}

Task 4: Signing a Message

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *n = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *d = BN_new();
  BIGNUM *M1 = BN_new();
  BIGNUM *M2 = BN_new();
  BIGNUM *S1 = BN_new();
  BIGNUM *S2 = BN_new();
  
  BN_hex2bn(&n, "DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5");
  BN_hex2bn(&e, "010001");
  BN_hex2bn(&d, "74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D");
  BN_hex2bn(&M1, "49206f776520796f752024323030302e");
  BN_hex2bn(&M2, "49206f776520796f752024333030302e");
  
  BN_mod_exp(S1, M1, d, n, ctx); //S1=M1^d mod n
  BN_mod_exp(S2, M2, d, n, ctx); //S2=M2^d mod n
  
  printBN("S1 = ", S1);
  printBN("S2 = ", S2);
  return 0;
}

可以看到虽然消息的变动很微小,但签名之后是完全不同的。

Task 5: Verifying a Signature

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *n = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *M = BN_new();
  BIGNUM *S1 = BN_new();
  BIGNUM *S2 = BN_new();
  BIGNUM *M1 = BN_new();
  BIGNUM *M2 = BN_new();
  
  BN_hex2bn(&n, "AE1CD4DC432798D933779FBD46C6E1247F0CF1233595113AA51B450F18116115");
  BN_hex2bn(&e, "010001");
  BN_hex2bn(&M, "4c61756e63682061206d697373696c652e");
  BN_hex2bn(&S1, "643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802F");
  BN_hex2bn(&S2, "643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6803F");
  
  BN_mod_exp(M1, S1, e, n, ctx); //M1=S1^e mod n
  BN_mod_exp(M2, S2, e, n, ctx); //M2=S2^e mod n
  
  if (BN_cmp(M1, M)==0)
    printf("S1:Valid\n");
  else 
    printf("S1:Not valid\n");
  
  if (BN_cmp(M2, M)==0)
    printf("S2:Valid\n");
  else 
    printf("S2:Not valid\n");
    
  return 0;
}

Task 6: Manually Verifying an X.509 Certificate

Step 1: Download a certificate from a real web server.

Step 2: Extract the public key (e, n) from the issuer’s certificate.

可以看到e为65537

Step 3: Extract the signature from the server’s certificate.

将签名复制到文件中

Step 4: Extract the body of the server’s certificate.

Step 5: Verify the signature.

代码如下

#include <stdio.h>
#include <openssl/bn.h>

#define NBITS 256

void printBN(char *msg, BIGNUM * a)
{
   /* Use BN_bn2hex(a) for hex string
    * Use BN_bn2dec(a) for decimal string */
   char * number_str = BN_bn2hex(a);
   printf("%s %s\n", msg, number_str);
   OPENSSL_free(number_str);
}

int main ()
{
  BN_CTX *ctx = BN_CTX_new();

  BIGNUM *n = BN_new();
  BIGNUM *e = BN_new();
  BIGNUM *M = BN_new();
  BIGNUM *S = BN_new();
  
  BN_hex2bn(&n, "CCF710624FA6BB636FED905256C56D277B7A12568AF1F4F9D6E7E18FBD95ABF260411570DB1200FA270AB557385B7DB2519371950E6A41945B351BFA7BFABBC5BE2430FE56EFC4F37D97E314F5144DCBA710F216EAAB22F031221161699026BA78D9971FE37D66AB75449573C8ACFFEF5D0A8A5943E1ACB23A0FF348FCD76B37C163DCDE46D6DB45FE7D23FD90E851071E51A35FED4946547F2C88C5F4139C97153C03E8A139DC690C32C1AF16574C9447427CA2C89C7DE6D44D54AF4299A8C104C2779CD648E4CE11E02A8099F04370CF3F766BD14C49AB245EC20D82FD46A8AB6C93CC6252427592F89AFA5E5EB2B061E51F1FB97F0998E83DFA837F4769A1");
  BN_hex2bn(&e, "10001");
  BN_hex2bn(&S, "04e16e023e0de32346f4e3963505933522020b845de27386d4744ffc1b27af3ecaadc3ce46d6fa0fe271f90d1a9a13b7d50848bd5058b35e20638629ca3ecccc7826e1598f5dca8bbc49316f61bd42ff6162e1223524269b57ebe5000dff40336c46c233770898b27af643f96d48dfbffefa281e7b8acf2d61ff6c8798a42c629abb108cff34487066b76d72c369f9394b683956bda1b36df477f3465b5c19ac4fb3746b8cc5f189cc93fe0c016f8817dc427160e3ed7330429ca92f3ba2788ec86fbad1130cd0c75e8c10fb012e379bdbacf7a1acba7ff892e7cb4144c815f9f3c4bbad515fbedec7ac86079f40ecb90bf6b28bccb5553366ba33c2c4f0a2e9");
  
  BN_mod_exp(M, S, e, n, ctx); //M=S^e mod n
  
  printBN("M = ", M);
  
  return 0;
}

经验证其后256比特位与第四步得到的哈希值一致

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值