引子

目前做一款金融产品,由于涉及到资金安全,采用动态公钥的方式,即客户端每次登录服务端返回一个不同的XML串,由公钥的模数和指数构成,我需要用这个串生成公钥加密相关信息。

服务端返回的XML串形如:

wVwBKuePO3ZZbZ//gqaNuUNyaPHbS3e2v5iDHMFRfYHS/bFw+79GwNUiJ+wXgpA7SSBRhKdLhTuxMvCn1aZNlXaMXIOPG1AouUMMfr6kEpFf/V0wLv6NCHGvBUK0l7O+2fxn3bR1SkHM1jWvLPMzSMBZLCOBPRRZ5FjHAy8d378=

AQAB

View Code

问题

对RSA不了解。

如何用所谓的模数和指数生成公钥来加密相关信息。

过程

熟悉RSA。先看下openssl库中RSA结构体的定义。

structrsa_st

{/*The first parameter is used to pickup errors where

* this is passed instead of aEVP_PKEY, it is set to 0*/

intpad;longversion;const RSA_METHOD *meth;/*functional reference if 'meth' is ENGINE-provided*/ENGINE*engine;

BIGNUM*n;

BIGNUM*e;

BIGNUM*d;

BIGNUM*p;

BIGNUM*q;

BIGNUM*dmp1;

BIGNUM*dmq1;

BIGNUM*iqmp;/*be careful using this if the RSA structure is shared*/CRYPTO_EX_DATA ex_data;intreferences;intflags;/*Used to cache montgomery values*/BN_MONT_CTX*_method_mod_n;

BN_MONT_CTX*_method_mod_p;

BN_MONT_CTX*_method_mod_q;/*all BIGNUM values are actually in the following data, if it is not

* NULL*/

char *bignum_data;

BN_BLINDING*blinding;

BN_BLINDING*mt_blinding;

};

View Code

开始推荐的博客中有关于RSA模数和指数的介绍,对应到结构中分别是其中的 n 和 e ,模反数对应d,最开始的质数因子对应 p和 q。n和e决定了公钥,n和d决定了私钥。结构体中其它元素不论,能知道的是模数和指数决定了公钥。

如果能生成一个der或者pem文件,就可以用系统的方法去获取公钥,如下:

//1 der证书的base64编码形式

NSString *cert = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBXAEq5487dlltn/+Cpo25Q3Jo8dtLd7a/mIMcwVF9gdL9sXD7v0bA1SIn7BeCkDtJIFGEp0uFO7Ey8KfVpk2Vdoxcg48bUCi5Qwx+vqQSkV/9XTAu/o0Ica8FQrSXs77Z/GfdtHVKQczWNa8s8zNIwFksI4E9FFnkWMcDLx3fvwIDAQAB";//2 解码base64

NSData *publicKeyFileContent =[NSData dataFromBase64String:cert];//3 创建der证书对象

certificate =SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);if (certificate ==nil) {

DLog(@"Can not read certificate from pub.der");returnnil;

}//4 验证证书

policy =SecPolicyCreateBasicX509();

OSStatus returnCode= SecTrustCreateWithCertificates(certificate, policy, &trust);if (returnCode != 0) {

DLog(@"SecTrustCreateWithCertificates fail. Error Code: %ld", returnCode);returnnil;

}//5 返回公钥

SecTrustResultType trustResultType;

returnCode= SecTrustEvaluate(trust, &trustResultType);if (returnCode != 0) {

DLog(@"SecTrustEvaluate fail. Error Code: %ld", returnCode);returnnil;

}//不管是否信任都会尝试返回公钥,也有可能被信任但是返不回公钥

publicKey =SecTrustCopyPublicKey(trust);if (publicKey ==nil) {

DLog(@"SecTrustCopyPublicKey fail");returnnil;

}

maxPlainLen= SecKeyGetBlockSize(publicKey) - 12;

View Code

一番尝试后没有搞定,之后转向第三方库,比如openssl,openssl用C++实现。可以借助该库用模数和指数构造公钥。在网上也找到一篇解决这个问题的博客:

unsigned char *base64_decode(const char* base64data, int*len) {

BIO*b64, *bmem;

size_t length=strlen(base64data);

unsignedchar *buffer = (unsigned char *)malloc(length);

b64=BIO_new(BIO_f_base64());

BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

bmem= BIO_new_mem_buf((void*)base64data, length);

bmem=BIO_push(b64, bmem);*len =BIO_read(bmem, buffer, length);

BIO_free_all(bmem);returnbuffer;

}

BIGNUM* bignum_base64_decode(const char*base64bignum) {

BIGNUM* bn =NULL;intlen;

unsignedchar* data = base64_decode(base64bignum, &len);if(len) {

bn=BN_bin2bn(data, len, NULL);

}

free(data);returnbn;

}

EVP_PKEY* RSA_fromBase64(const char* modulus_b64, const char*exp_b64) {

BIGNUM*n =bignum_base64_decode(modulus_b64);

BIGNUM*e =bignum_base64_decode(exp_b64);if (!n) printf("Invalid encoding for modulus\n");if (!e) printf("Invalid encoding for public exponent\n");if (e &&n) {

EVP_PKEY* pRsaKey =EVP_PKEY_new();

RSA* rsa =RSA_new();

rsa->e =e;

rsa->n =n;

EVP_PKEY_assign_RSA(pRsaKey, rsa);returnpRsaKey;

}else{if(n) BN_free(n);if(e) BN_free(e);returnNULL;

}

}void assert_syntax(int argc, char**argv) {if (argc != 4) {

fprintf(stderr,"Description: %s takes a RSA public key modulus and exponent in base64 encoding and produces a public key file in PEM format.\n", argv[0]);

fprintf(stderr,"syntax: %s \n", argv[0]);

exit(1);

}

}

View Code

生成pem文件之后可以从pem文件里面读取公钥加密相关信息。

注解

ASN.1:ASN.1抽象语法标记(Abstract Syntax Notation One) ASN.1是一种 ISO/ITU-T 标准,描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指 代,也不用去管到底是什么样的应用程序。标准的ASN.1编码规则有基本编码规则(BER,Basic Encoding Rules)、规范编码规则(CER,Canonical Encoding Rules)、唯一编码规则(DER,Distinguished Encoding Rules)、压缩编码规则(PER,Packed Encoding Rules)和XML编码规则(XER,XML Encoding Rules)。

x.509 : 常见通用的证书格式。

der:DER是ASN.1编码规则的其中一种。x.509证书通过DER编码(ASCII)后缀是:.DER .CER .CRT,通过PAM编码(Base64)的后缀是:.PEM .CER .CRT。.cer/.crt是用于存放证书,它是2进制形式存放的,不含私钥。

pem文件 : der文件经过base64转码后的文件。

(Email: yangxu0905@foxmail.com)

rsa java模数_RSA加密:利用模数和指数生成公钥加密相关推荐

  1. js rsa java解密_RSA使用js加密,使用java解密

    RSA算法使用javascript加密,使用java解密,提供完整代码及例子下载. javascript加密介绍参见另一篇:javascript使用RSA加密提交数据.本篇的例子使用的js是上一篇中提 ...

  2. c rsa java私钥_RSA,JAVA私钥加密,C#公钥解密

    做这个东西在坑里爬了3天才爬出来,记录下供园友参考.C#程序员一枚,项目需要和Java做数据交互,对方甩了段密文和一个CER证书给我,然后我要对其密文进行解密. RSA 非对称加密,对方用私钥加密,我 ...

  3. java rsa 文件加密解密_RSA 加密、解密(自己生成加密解密文件)

    本文是自己阅读了网上的高人们的文章之后,实现功能后总结出来的,方便自己方便他人,不喜勿喷 加密解密需要生成公钥.私钥文件步骤 1.打开终端 输入 openssl 5F88AA4A-3913-4CBC- ...

  4. java excel导出 jxl_JAVA利用JXL导出/生成 EXCEL

    jxl是java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持非常好,A ...

  5. java实现ecc加密:通过AES生成公钥加密数据,ECC加密公钥

    成功: 本文通过.java语言实现ECC+AES混合加密.ECC加密算法具有密钥分配与管理简单,安全强度高等优点,AES的加密算法具有速度快,强度高,便于实现等优点.Ecc椭圆曲线算法对AES公钥进行 ...

  6. java jxl 创建excel_JAVA利用JXL导出/生成 EXCEL

    jxl是java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持非常好,A ...

  7. rsa java模数_RSA公私钥获取模数和质数

    实际项目中,发现前端在生成公钥对象的时候并不是使用这种方式,而是通过对应的模数跟质数来构造公钥对象的,这样的话,需要进一步将生成的公钥取出对应的模数和质数.openssl.java api都可以将质数 ...

  8. 基于java的rsa加密程序_RSA rsa加密程序,rsa java源码和 rsa的jsp Crypt_De algrithms 解密 238万源代码下载- www.pudn.com...

    文件名称: RSA下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 169 KB 上传时间: 2014-04-23 下载次数: 0 提 供 者: 姚双奇 详细说明: ...

  9. java发送加密报文_RSA加密---从后台到客户端实现报文加解密

    RSA是当前最流行的非对称加密方式,使用公钥加密使用密钥解密,如何妥善的保管密钥就成了关键. 动态生成密钥 工具类 package com.yitong.utils; import java.secu ...

最新文章

  1. 《程序设计与数据结构》实验四报告
  2. sequoiadb sdbexprt 导入工具进阶使用
  3. 符乐安:2020年短视频创作将迎来新的高峰
  4. SAP Fiori Elements 应用里的 Title 显示的内容是从哪里来的
  5. CodeForces - 1152B二进制+思维
  6. 【转】深入理解Windows消息机制
  7. 在创投界有个公开的秘密
  8. Ubuntu学习日记--Lesson1:Linux基础和常用命令
  9. Java版扫雷小游戏
  10. Visual Studio 2012安装教程
  11. 日系P2P原理探究(二) — Winny, 日本崛起
  12. Uber自动驾驶车祸判决:人没监督车?车没监督人?
  13. numpy的getA()/getA1()/getH()/getI()函数
  14. python+opencv代码给证件照换底色(别再用PS啦)(转载)
  15. vue 监听input停止输入后发送请求
  16. matlab 纵向的虚线,纵向减速标记符号中间是虚线可以变道吗
  17. win10控制台打开远程桌面连接
  18. [学习笔记]使用GNU Toolchain在STM32上跑起一个最小OS
  19. vivado 时序例外约束
  20. 使用Lodop进行web 打印(jatoolsPrinter,墙外打印控件 楚琳Web打印控件)

热门文章

  1. 英雄联盟手游拳头账号注册
  2. java打印32位二进制
  3. 如何用ps设计出一张吸引人眼球的创意节日海报?
  4. MATLAB时频工具箱函数说明(包含工具箱的下载,安装,使用)
  5. STEP 标准基础概念-刘亚龙
  6. HP G42-474TX在Win分区方法
  7. 分布电容和杂散电容_寄生电容 分布电容
  8. CAD软件中如何统一文字字高?
  9. 【原创】RPA在BPO领域的场景分享-中科云创CEO每日分享
  10. clion:输出中文乱码终极解决方案