openssl 1.1.0e installation on macos 10.12(sierra)

openssl 1.1.0e installation on macos 10.12(sierra)

第1次尝试,失败:

./config –prefix=/usr
permission denied

sudo ./config –prefix=/usr
Configured

make
permission denied
sudo make
sudo make test
sudo make install

unable to create /usr/include

看来, macos不允许往/usr/安装东西,还是安装到默认的目录/usr/local/下吧:
重来

sudo make clean

./config
permission denied

sudo ./config

sudo make

sudo make test
md2 is not supported on this system
rc5 is not supported on this system

sudo make install

最终安装到了 /usr/local/下了
这样,机器上有两个版本的openssl可执行程序
一个是系统自带的,在/usr/bin/里面,一个在/usr/local/bin/里面

————

不过 Xcode 似乎无法访问 /usr/…下面的库文件
编译程序报错:

Undefined symbols for architecture x86_64:
“_AES_decrypt”, referenced from:
_main in main.o
“_AES_encrypt”, referenced from:
_main in main.o
“_AES_set_decrypt_key”, referenced from:
_main in main.o
“_AES_set_encrypt_key”, referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

在General下欲添加libcrypto.a到Frameworks里面,但弹出的对话框根本不允许访问/usr
怎么办?

按组合键(和在Finder里面Go to folder一样): Command+Shift+G
手工输入 /usr/local/lib/ 即可

RSA Private key .pem file composition

好奇心驱使我看了一眼我产生的RSA密钥中的两个素数, 看到构成如下:

openssl
rsa -in key.pem -text

modulus: 1024 bits
publicExponent: 17 bits
privateExponent: 1024 bits
prime1: 512 bits
prime2: 512 bits
exponent1: 512 bits
exponent2: 512 bits
coefficient: 360 bits

前面5个很容易理解,分别是 n, e, d, p, q
其中:
n = p ✖︎ q
e=65537(基本是个常数,当前openssl genrsa仅支持3 and 65537,默认使用65537)

后面3参数是什么?

exponent1: d % (p-1) 简称dp
exponent2: d % (q-1) 简称dq
coefficient: 又称InverseQ,它满足 q逆 ✖︎ q = 1 % p

后面这三个数可以加快解密过程, https://en.wikipedia.org/wiki/RSA_(cryptosystem) 有说明

解密 m = c的d次方 % n
可以用下面的过程求得:
m1 = c的dp次方 % p
m2 = c的dq次方 % q
h = ( q逆 ✖︎ (m1 – m2 ) ) % p
m = m2 + h ✖︎ q
这4步所用到的数都比n要小得多

PEM_read_RSAPublicKey and PEM_read_RSAPublicKey

PEM_read_RSAPrivateKey
PEM_read_RSAPublicKey
PEM_read_RSA_PUBKEY

写了一段程序来测试RSA加解密,结果发现无论如何公钥怎么也读不出来,后来发现读取私钥使用PEM_read_RSAPrivateKey, 但读取公钥却不能用PEM_read_RSAPublicKey, 那用什么呢?要用PEM_read_RSA_PUBKEY

why?

打开两个文件看一看,发现文件格式不一样啊(public key文件开头没有RSA标志):

private key:
—–BEGIN RSA PRIVATE KEY—–

—–END RSA PRIVATE KEY—–

publick key:
—–BEGIN PUBLIC KEY—–

—–END PUBLIC KEY—–

PEM_read_RSAPublicKey 用于读取下面格式的公钥文件:
—–BEGIN RSA PUBLIC KEY—–

—–END RSA PUBLIC KEY—–

而 PEM_read_RSA_PUBKEY 用于读取这样的:
—–BEGIN PUBLIC KEY—–

—–END PUBLIC KEY—–

至于为什么这样,openssl的一贯风格是不注释,无文档,让你自己读代码琢磨去吧。

Repetitive Strain Injury

Repetitive Strain Injury 重复性劳损

https://web.eecs.umich.edu/~cscott/rsi.html
上面这篇文章是我读过的最好的关于RSI的文章。

我与RSI的对抗历史:
2002年开始,右手指头疼,发现与用鼠标有关。当时有人发明了立式鼠标,于是买来用,结果发现效果适得其反。据发明人的解释,右手放在桌面上,自然的状态是手心向左。而在用鼠标时,手心却向下。这样就长期处于非自然状态下,会导致问题。说得似乎有道理。于是我就买了。结果一用,发现,尽管手的状态保持在“自然状态”,但由于鼠标在左边,而不是下边,点击时力度必须相当大才行,结果是为了解决一个问题却带来另外一个问题,一个更大的问题。
由于疼痛并不严重,当时并没有将其当一回事,再也没有采取任何措施防止疼痛加重。
到了2008年,情况越来越严重。终于有一天,无法工作了。右手食指,中指都疼。按鼠标用不上力。表面看去,手没有任何异常。非常奇怪的是,干任何事都没有问题,除了按下鼠标!例如用筷子吃饭,没有任何不适,没有任何疼痛和症状,但是一碰鼠标,中指根部剧痛。
不得已,只好换用左手。刚开始很不灵巧,不过,过了一段时间,左手就适应了。
不过我知道,左手发展到右手那种地步,是迟早的事。
怎么避免呢?
我采取的办法:
0. 桌椅绝对不能凑合。
1. 用苹果的触摸板来代替鼠标。遗憾的是这个只能在macos下用。在Windows下它功能不全,无法完全代替鼠标。
2. 用wacom的数位板和手写笔,曾经买过两个,办公室和家里各有一个。用起来还行,但效率较低。毕竟不是鼠标,用其代替鼠标,不那么方便。必须双手操作才行。
3. 声控。从美国邮购了一套声控软件。结果发现非常不实用,识别率太低了,试了试放弃。我的目标其实很简单,你只要能听懂我有限的指令就行了。我的需求是,你提供自定义配置,只识别特定的话语并将其翻译成鼠标动作或键盘操作。但该软件没有这样的功能,它的目标在英语听写上。
4. 脚控。我的问题主要在用鼠标上,右手不听使唤,最严重的时候中指无力按下鼠标按键,移动倒不成问题。因此我最基本的需求是:不动手按下鼠标。买过脚控键盘,三个大按钮,可自定义功能。刚开始时我将其定义成鼠标左中右键,后来三个全部都定义成了左键(因为经常一脚同时踩中两键)。用了一段时间,发现腿开始疼,赶快放弃。
5. 尽量少用手。过去上网下棋,常常昼夜奋战,现在基本不下了,偶尔下下,使用触摸板和iPad来操作。
6. 使用AntiRSI软件,其实就是提醒功能,这些软件会在你工作持续一段时间后提醒你休息一会。

openssl_uplink no openssl_applink

调用PEM_read_RSAPrivateKey时程序直接退出,跟踪发现,执行到了一个unimplemented(),此函数调用OPENSSL_showfatal后就exit了
fatal内容如下:
openssl_uplink no openssl_applink

原因:
openssl 在一些文件I/O时不用标准的C库函数,而是自己用了22个函数代替,例如 在打开文件时不直接使用 fopen, 而是使用 UP_fopen
但是在libeay32.dll中并没有实现这些函数。它要求调用者来实现,反过来供自己使用。调用者怎么实现呢?这个openssl倒是已经准备好了,调用者需要将applink.c添加到自己的工程项目中,重新编译即可。

在applink.c里面,我们看到,UP_fopen还是#include使用标准的C库函数。
为什么不直接fopen,而要绕这么大一个圈子呢?
我们姑且假设openssl有充分的理由这么做,那么第2个问题是:
为什么不直接在libeay32.dll中实现这22个函数,而要调用者实现?

第1个问题,搜索了一下,发现了一个答案:

https://github.com/openssl/openssl/pull/1356

Mixing threading models is only one particular case. I mean issue is wider than that. Intention was to facilitate mixing different compilers and/or versions, or even compiler flags. I mean say you want to compiler your application with debugging flags. Without applink you’d have to recompile even OpenSSL dlls with same flags… Or consider I’ve got dll from somebody else, without applink you’d have to figure out which compiler version was used and use same. With applink you can use any compiler, not even from same vendor. Once again, if you use interfaces that actually rely on applink. As correctly pointed out those accepting FILE * and Unix-like fd from application. And once again, recommendation is avoid those in new application code.

感到理由不那么充分

继续往下读

threading models.
During compilation, the MSVCRT assumes the layout of FILE objects. In multi-threaded builds, FILE objects include an extra CRITICAL_SECTION field to provide locking. The MSVCRT maintains a list of these objects in an array _iob. If one part of an application is built with a different threading model it can lead to memory corruption of the _iob array, lost data and application crash.

Applink solves this by moving all file i/o out of OpenSSL and into your application. But this introduces a problem for those developers working in scripting languages, where the application is the interpreter (ex: python). It may not be practical to request users to rebuild the interpreter.

In the case where you are developing c extensions for your scripting language you can instead arrange to include in your extension and from there invoke OPENSSL_SetApplink. This requires that your extension be compiled using the same threading model as the application and as OpenSSL.

这个理由足够了。

第1个问题弄明白了后,发现第2个问题不需要问了。因为假如在libeay32.dll中实现,那么效果将是这样的:
fopen = UP_fopen
UP_fopen(FILE *fp, int mode){
fopen(fp, mode)
}
哈哈,这没有解决任何问题

关键: openssl不知道你的程序使用什么模式编译的,只有你自己知道,因此你要自己来避免模式不匹配造成的内存泄露