如何在 C++ 中将 RSA* 打印为字符串?

2023-12-11

如何在 C++ 中将 RSA* 正确打印为字符串?

我在用OpenSSL。似乎没有.c_str()方法对吧?


#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

#include <memory>
using std::unique_ptr;

#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>  

#include <cassert>
#define ASSERT assert

using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
using BIO_MEM_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;

int main(int argc, char* argv[])
{
    int rc;

    RSA_ptr rsa(RSA_new(), ::RSA_free);
    BN_ptr bn(BN_new(), ::BN_free);
    BIO_MEM_ptr bio(BIO_new(BIO_s_mem()), ::BIO_free);

    rc = BN_set_word(bn.get(), RSA_F4);
    ASSERT(rc == 1);

    rc = RSA_generate_key_ex(rsa.get(), 2048, bn.get(), NULL);
    ASSERT(rc == 1);

    rc = RSA_print(bio.get(), rsa.get(), 0);
    ASSERT(rc == 1);

    BUF_MEM* mem = NULL;
    BIO_get_mem_ptr(bio.get(), &mem);
    ASSERT(mem != NULL);

    string s;
    if(mem->data && mem->length)
        s.assign(mem->data, mem->length);

    if(s.length())
        cout << s << endl;
    else
        cout << "Failed to retrieve key" << endl;

    return 0;
}

典型的运行:

$ ./test-openssl.exe
Private-Key: (1024 bit)
modulus:
    00:9e:44:ab:26:da:2d:42:3f:ea:06:1f:3b:80:22:
    39:0f:89:ee:38:ba:f9:49:a6:7d:69:be:f7:b8:43:
    30:db:7b:32:82:09:89:c4:84:43:af:75:33:22:40:
    07:ad:43:c8:56:54:f3:c5:6e:a5:bc:a6:b2:83:49:
    a4:07:8e:d3:b8:a1:5b:c9:55:04:0a:01:73:12:85:
    93:ef:20:0b:29:2e:a8:2d:4f:4a:1d:ad:31:b8:81:
    dd:57:49:3c:d1:57:71:29:c3:34:1c:cf:ba:31:86:
    cb:d6:d7:92:b9:3c:84:ca:2e:f6:fa:85:0a:86:e4:
    b1:e0:1e:00:86:d9:c6:14:37
publicExponent: 65537 (0x10001)
privateExponent:
    5e:1d:7f:99:af:0c:52:e5:27:09:54:f1:51:15:08:
    d1:90:b8:34:cc:1b:0a:0d:13:6f:1a:bc:bc:ba:58:
    07:6c:8f:70:7c:b3:8c:45:0a:ea:ff:ca:d4:87:37:
    09:75:d1:60:65:4c:41:0f:b7:47:23:e9:eb:e0:92:
    c6:5b:cc:d2:82:d5:f3:42:75:d4:88:95:35:20:62:
    f9:9a:18:df:6b:5b:ff:6c:97:11:63:d6:24:2c:86:
    bb:be:c1:ed:a3:87:8e:78:70:7a:c8:fc:73:9c:53:
    70:eb:ff:06:b9:91:be:81:56:a5:25:71:d3:54:09:
    04:ea:8d:1e:8e:48:eb:c1
prime1:
    00:cc:25:66:b7:dc:66:64:eb:5c:f2:15:9f:7b:66:
    c0:9e:8d:51:63:e0:8b:15:73:64:54:d2:62:35:a6:
    14:29:20:ba:92:3e:dc:d4:32:6a:c6:ba:45:56:94:
    3e:77:e1:ab:e0:60:cf:12:2b:09:1f:45:0e:2c:b2:
    49:1e:85:66:ef
prime2:
    00:c6:78:0f:44:19:cc:74:22:32:58:d1:ee:a7:6f:
    fa:b4:57:a4:4a:7c:7a:52:53:c8:52:48:34:05:b4:
    59:3f:18:a3:88:17:fd:ae:2e:54:d7:83:2c:a9:bf:
    52:7b:f4:e9:af:02:61:99:fa:35:4a:b0:e4:a0:8c:
    5f:f8:d8:67:39
exponent1:
    00:a3:41:7d:c5:a7:72:13:5e:cd:b3:a3:6b:28:ca:
    61:5b:ea:73:9e:45:e1:b4:43:d5:86:a7:c0:76:5a:
    dc:60:8f:95:e4:82:75:23:15:36:a2:ba:2f:dd:2f:
    2c:4d:be:a1:2f:0c:fc:4b:f1:32:98:59:27:1e:c3:
    6d:0a:05:70:ed
exponent2:
    00:97:d5:de:08:01:9c:b2:f4:3e:84:49:07:45:bd:
    9b:95:40:bf:85:e4:b9:48:26:a4:c8:9e:48:7e:5c:
    bd:32:52:4d:39:9e:f1:0a:c2:93:51:d5:1e:e4:36:
    64:8a:44:92:4a:bb:8d:a3:d9:11:d0:34:88:94:73:
    10:31:36:8d:b1
coefficient:
    1d:97:1c:37:72:66:87:6f:a8:10:5d:bf:02:31:3d:
    69:bb:a8:13:78:cb:20:d7:70:ee:f9:ba:1e:a9:e1:
    ca:5b:db:a8:12:64:39:32:4f:0b:b8:0e:0f:fc:2c:
    ec:89:25:06:bf:84:d7:94:e5:18:bd:80:f4:74:ba:
    5e:0a:4c:24

如果您不喜欢该输出,您可以访问RSA直接会员。例如:

// RSA object 'owns' the BIGNUM. Don't destroy it.
BIGNUM* n = rsa.get()->n;
BIGNUM* e = rsa.get()->e;
BIGNUM* d = rsa.get()->d;

string s;

BIO_reset(bio.get());
mem = NULL;

rc = BN_print(bio.get(), n);
ASSERT(rc == 1);

BIO_get_mem_ptr(bio.get(), &mem);
if(mem && mem->data && mem->length)
    s.assign(mem->data, mem->length);

if(s.length())
    cout << "Modulus: " << endl << s << endl;
else
    cout << "Failed to retrieve modulus" << endl;

BIO_reset(bio.get());
mem = NULL;

rc = BN_print(bio.get(), e);
ASSERT(rc == 1);

BIO_get_mem_ptr(bio.get(), &mem);
if(mem && mem->data && mem->length)
    s.assign(mem->data, mem->length);

if(s.length())
    cout << "Public exponent: " << endl << s << endl;
else
    cout << "Failed to retrieve public exponent" << endl;

BIO_reset(bio.get());
mem = NULL;

rc = BN_print(bio.get(), d);
ASSERT(rc == 1);

BIO_get_mem_ptr(bio.get(), &mem);
if(mem && mem->data && mem->length)
    s.assign(mem->data, mem->length);

if(s.length())
    cout << "Private exponent: " << endl << s << endl;
else
    cout << "Failed to retrieve private exponent" << endl;

输出将类似于:

Modulus: 
E00226E63C7BE6A23990592F3F861393B1F563D7CF57699619E6ED558EFA6D64C326203825E163EF
28B7B3608C68B8A9F1A5952FA8E4C42A4F6066BE6D1502D20894577C91DB94F6F596891DCF9532E2
19FBAEA1201215E014DEE8A270BEABDFC7D00860BF3C08A26707CADAECCF9A2229984C23F198691E
B59D26D4AC8460BD
Public exponent: 
10001
Private exponent: 
3D3E99600D5D5ABB33BDD184677BC2D278AF3CB2FE4F49E0EE08030F875DD496DDFC08871164442C
591790856F1E1A8EEC30774F667FD55A34058951BB052995BC24A80AAA547E1764FB33500007A743
C9B41F376F655EB8BDD729172F8592886C299994565F9F72A0235CBB22AA33BD1A2D20AF07DCBAC5
6DB22E4DCBC4DCC1

如果您喜欢第一个示例的格式(用冒号分隔的八位字节),那么请看一下ASN1_bn_print。您可以用它来打印RSA轮流担任成员。RSA_print and RSA_print_fp内部调用ASN1_bn_print。有一个例子在c 中的 OpenSSL 命令获取 RSA 中公钥的模数.

BIGNUM* n = rsa.get()->n;

int req = BN_num_bytes(n) + 4;
unsigned char* ptr = (unsigned char*)OPENSSL_malloc(req);

rc = ASN1_bn_print(bio.get(), "Modulus:", n, ptr, 0);
ASSERT(rc == 1);

BIO_get_mem_ptr(bio.get(), &mem);
if(mem && mem->data && mem->length)
    s.assign(mem->data, mem->length);

if(s.length())
    cout << s << endl;
else
    cout << "Failed to retrieve modulus" << endl;

它将产生类似于以下内容的输出:

Modulus:
    00:bf:49:fa:f2:30:21:42:de:91:60:f3:02:37:87:
    86:f4:eb:85:2c:95:86:42:69:6f:bc:cf:3f:27:9e:
    17:b6:44:06:5f:e7:ea:9f:e8:38:a7:5a:d5:da:9f:
    4b:26:df:78:15:d7:df:22:c0:16:12:77:f9:18:aa:
    85:01:21:3a:b0:ae:39:b8:07:cd:d4:2c:a3:0b:1c:
    df:be:09:03:09:76:5f:a1:1e:c0:00:8e:bf:b2:40:
    e2:3c:eb:d1:85:6f:7a:ab:35:c3:3a:c4:23:db:39:
    0c:d0:2b:39:b3:a5:a5:08:a2:e4:00:d5:0b:b0:87:
    62:ae:7c:a4:6c:e6:1c:d6:c9

您还可以使用BN_bn2dec和朋友。例如:

BIGNUM* n = rsa.get()->n;
cout << "BN_bn2dec:" << endl;
cout << BN_bn2dec(n) << endl;

它将产生:

BN_bn2dec: 
12243739000135209335165415265342326792394455644180015057748915050940947919482400
64106225312022889083399949792870649447719809295883754268473265926413766309145047
08000254475023744104439182803717332048247971986885955229841406443364223719542912
385690146029374797423322891147172613041161904860242946608474463378207
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C++ 中将 RSA* 打印为字符串? 的相关文章

  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • Objective-C 中发送给对象的消息可以被监听或者打印出来吗? [复制]

    这个问题在这里已经有答案了 可能的重复 Objective C 中拦截方法调用 https stackoverflow com questions 1618474 intercept method call in objective c 如
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 将 MQTTNet 服务器与 MQTT.js 客户端结合使用

    我已经启动了一个 MQTT 服务器 就像this https github com chkr1011 MQTTnet tree master例子 该代码托管在 ASP Net Core 2 0 应用程序中 但我尝试过控制台应用程序 但没有成
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 按 Esc 按键关闭 Ajax Modal 弹出窗口

    我已经使用 Ajax 显示了一个面板弹出窗口 我要做的是当用户按 Esc 键时关闭该窗口 这可能吗 如果有人知道这一点或以前做过这一点 请帮助我 Thanks 通过以下链接 您可以通过按退出按钮轻松关闭窗口 http www codepro
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • System.IO.FileNotFoundException:找不到网络路径。在 Windows 7 上使用 DirectoryEntry 对象时出现异常

    我正在尝试使用 DirectoryEntry 对象连接到远程 Windows 7 计算机 这是我的代码 DirectoryEntry obDirEntry new DirectoryEntry WinNT hostName hostName
  • C++ 条件编译

    我有以下代码片段 ifdef DO LOG define log p record p else define log p endif void record char data 现在如果我打电话log hello world 在我的代码中
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • Oracle Data Provider for .NET 不支持 Oracle 19.0.48.0.0

    我们刚刚升级到 Oracle 19c 19 3 0 所有应用程序都停止工作并出现以下错误消息 Oracle Data Provider for NET 不支持 Oracle 19 0 48 0 0 我将 Oracle ManagedData
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看

随机推荐