使用 openssl/bn.h 将 c++ 痛饮到 python
Posted
技术标签:
【中文标题】使用 openssl/bn.h 将 c++ 痛饮到 python【英文标题】:swig c++ to python with openssl/bn.h 【发布时间】:2017-10-18 15:25:53 【问题描述】:我正在尝试使用 SWIG 创建一个 *.so 文件以供在 Python 中进一步使用。特别是我正在使用来自 openssl 的一些库(例如 opensll/bn.h)。但不知何故,它返回错误ImportError: [...]/auxchash.so: undefined symbol: BN_bn2hex
。
我有file.cpp、auxchash.cpp:
#include auxchash.h
int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk)
BN_CTX *ctx = BN_CTX_new();
BIGNUM *bn_p = BN_new();
BIGNUM *bn_q = BN_new();
BIGNUM *bn_g = BN_new();
BIGNUM *bn_hk = BN_new();
BIGNUM *bn_tk = BN_new();
BIGNUM *bn_two = BN_new();
BN_CTX_init(ctx);
BN_dec2bn(&bn_two, "2"); //initialize a BIGNUM with value 2
//on non-unix platform needs to initialize the PRNG with randomness
//or BN_generate_prime_ex may fail
//computing the safe prime p and q = (p-1)/2
BN_generate_prime_ex(bn_p, bits, 1, NULL, NULL, NULL);
BN_sub(bn_q, bn_p, BN_value_one());
BN_div(bn_q, NULL, bn_q, bn_two, ctx);
//finding the generator g (for the group QR_p)
BN_rand_range(bn_g, bn_p);
BN_mod_exp(bn_g, bn_g, bn_two, bn_p, ctx);
//choosing the keys hk and tk
BN_rand_range(bn_tk, bn_q);
BN_mod_exp(bn_hk, bn_g, bn_tk, bn_p, ctx);
//converting from BIGNUM to hex
p = BN_bn2hex(bn_p);
q = BN_bn2hex(bn_q);
g = BN_bn2hex(bn_g);
hk = BN_bn2hex(bn_hk);
tk = BN_bn2hex(bn_tk);
//freeing the resources
BN_CTX_free(ctx);
BN_free(bn_two);
BN_free(bn_p);
BN_free(bn_q);
BN_free(bn_g);
BN_free(bn_hk);
BN_clear_free(bn_tk);
return 0;
文件.h、auxchash.h:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<openssl/bn.h>
#include<openssl/sha.h>
#include<openssl/rand.h>
int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk);
swig 模块的 file.i,auxchash.i:
%module auxchash
%
#define SWIG_FILE_WITH_INIT
#include "auxchash.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<openssl/bn.h>
#include<openssl/sha.h>
#include<openssl/rand.h>
%
%include "typemaps.i"
%include "cstring.i"
%cstring_bounded_output(char *p, 1024);
%cstring_bounded_output(char *q, 1024);
%cstring_bounded_output(char *g, 1024);
%cstring_bounded_output(char *hk, 1024);
%cstring_bounded_output(char *tk, 1024);
extern int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk);
最后一个文件 setup.py 来创建所有需要的 swig 文件,setup.py:
from distutils.core import setup, Extension
auxchash_module = Extension('_auxchash',
sources=['auxchash_wrap.cxx', 'auxchash.cpp'],
)
setup (name = 'auxchash',
version = '0.1',
author = "SWIG Docs",
description = """Simple swig example from docs""",
ext_modules = [auxchash_module],
py_modules = ["auxchash"],
)
而且都是用终端命令编译的:
swig -c++ -python auxchash.i
python setup.py build_ext --inplace
到目前为止一切顺利,编译时没有错误。但是当我运行 python main 时:
import auxchash
res,p,q,g,hk,tk = auxchash.keygen(10)
它给了我以下错误:
File: "[...]/auxchash.py" import auxchash
File: "[...]/auxchash.py" auxchash=swig_import_helper()
File: "[...]/auxchash.py" return=importlib.import_module('_auxchash')
File: "[...]/__init.py__" __import__(name)`
ImportError: [...]/auxchash.so: undefined symbol: BN_bn2hex
我不知道怎么弄。
【问题讨论】:
快速阅读,我认为您需要int keygen(int bits, char **p, char **q, char **g, char **hk, char **tk)
,以便该函数可以更改调用者中的指针。类似*p = BN_bn2hex(bn_p)
。
关于auxchash.so: undefined symbol: BN_bn2hex
,ldd auxchash.so
显示什么?是否依赖于libcrypto.so
?
是的@jww 你是对的,你写的绝对正确。但即使使用 swig 和 char **,我也遇到了麻烦。我决定采用这种方法,因为我无法在 swig 中处理指向 char * 的双指针。看到这个link。
如果你为你的其他问题展示了真正的工作代码,我早就回答过了。没有真正的代码,它只是在浪费时间。不过,您可以完全明智地包装 char**
,如果您真的可以展示这样一个有效的功能。
@Flexo 你说得对。抱歉,这是我的第一个问题,我是 *** 的新手。之前的问题我删了,这里写的更好link。
【参考方案1】:
您需要将您的模块与 OpenSSL 相关联,例如:
auxchash_module = Extension('_auxchash',
sources=['auxchash_wrap.cxx', 'auxchash.cpp'],
libraries=['crypto', 'ssl'],
)
(您可能只需要该列表中的加密,我现在不太记得/告诉)
【讨论】:
非常感谢!是的,添加库参数,它似乎工作。 (: 它有效,但现在我遇到了另一个问题。在我的 python main 上打印返回变量会打印一些难以辨认的字符。另一方面,在 C++ 函数内部,打印相同的值我得到了正确的值。所以就好像swing模块的输出有问题。但是%cstring_bounded_output
应该正确返回一个字符 *。这是链接到图书馆吗?
为了更好地理解,我尝试将简单字符串“hello”写入返回变量。 python main 无法正确获取它们(即它仍然打印难以辨认的字符。
我真的不知道你的 keygen 函数实际上做了什么,因为你没有展示它,或者你在测试用例中写了什么。但您可能没有正确理解输出参数的语义。
问题解决了!它只是分配东西。不要使用p = BN_bn2hex(bn_p)
,只需使用库函数strcpy(p ,BN_bn2hex(bn_p)
。感谢@Flexo。以上是关于使用 openssl/bn.h 将 c++ 痛饮到 python的主要内容,如果未能解决你的问题,请参考以下文章