分类 OpenSSL 下的文章

“OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连线者的身份。这个包广泛被应用在互联网的网页服务器上。 其主要库是以C语言所写成,实现了基本的加密功能,实现了SSL与TLS协议。”

1.编译zlib

wget http://zlib.net/zlib-1.2.11.tar.gz
tar -xzf zlib-1.2.11.tar.gz
cd zlib-1.2.11/
./configure --prefix=/home/const
make && make install

2.编译c-ares

wget https://c-ares.haxx.se/download/c-ares-1.15.0.tar.gz
tar xvf c-ares-1.15.0.tar.gz
cd c-ares-1.15.0
../configure --prefix=/home/const
make && make install

3.编译OpenSSL

wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
tar xvf openssl-1.1.1k.tar.gz
./Configure --prefix=/home/const no-asm -shared linux-x86_64
make && make install

4.编译cURL

wget https://curl.se/download/curl-7.76.1.tar.xz 
tar xvf curl-7.76.1.tar.xz 
cd curl-7.76.1
./configure --prefix=/home/const CPPFLAGS="-I/home/const/include" LDFLAGS="-L/home/const/lib" LIBS=" -lssl -lcrypto -lz -ldl -lpthread"  --disable-werror --enable-curldebug --with-ssl=/home/const --enable-zlib --enable-ares

1. Go run shell script or Go run shell string

curl := "curl -v https://const.net.cn"
cmd := exec.Command("bash", "-c", curl)
stdout, err := cmd.CombinedOutput()
if err != nil {
    fmt.Println("curl " + err.Error())
    return
}
fmt.Println(string(stdout)) 

2.输出结果

  • Uses proxy env variable https_proxy == 'socks5://127.0.0.1:1080'
  • Trying 127.0.0.1:1080...
  • TCP_NODELAY set % Total % Received % Xferd Average Speed Time Time Time Current

                                 Dload  Upload   Total   Spent    Left  Speed   0     0    0     0    0     0      0      0 --:--:-- --:--:--

    --:--:-- 0

  • SOCKS5 communication to const.net.cn:443
  • SOCKS5 connect to IPv4 43.129.233.128:443 (locally resolved)
  • SOCKS5 request granted.
  • Connected to 127.0.0.1 (127.0.0.1) port 1080 (#0)
  • ALPN, offering h2
  • ALPN, offering http/1.1
  • successfully set certificate verify locations:
  • CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs } [5 bytes data]
  • TLSv1.3 (OUT), TLS handshake, Client hello (1): } [512 bytes data]
  • TLSv1.3 (IN), TLS handshake, Server hello (2): { [122 bytes data]
  • TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): { [25 bytes data]
  • TLSv1.3 (IN), TLS handshake, Certificate (11): { [2780 bytes data]
  • TLSv1.3 (IN), TLS handshake, CERT verify (15): { [264 bytes data]
  • TLSv1.3 (IN), TLS handshake, Finished (20): { [52 bytes data]
  • TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): } [1 bytes data]
  • TLSv1.3 (OUT), TLS handshake, Finished (20): } [52 bytes data]
  • SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
  • ALPN, server accepted to use http/1.1
  • Server certificate:
  • subject: CN=const.net.cn
  • start date: May 19 00:00:00 2021 GMT
  • expire date: May 18 23:59:59 2022 GMT
  • subjectAltName: host "const.net.cn" matched cert's "const.net.cn"
  • issuer: C=CN; O=TrustAsia Technologies, Inc.; OU=Domain Validated SSL; CN=TrustAsia TLS RSA CA
  • SSL certificate verify ok. } [5 bytes data]

GET / HTTP/1.1
Host: const.net.cn
User-Agent: curl/7.68.0
Accept: /

......

OpenSSL 生成 SM2 密钥

openssl ecparam -name SM2 -genkey -out sm2_ec.key 
cat sm2_ec.key 
-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIB9dGHE5+6AD9DGmA8g/cEqn8HYTMBhbM+g2XJ16RqZ1oAoGCCqBHM9V
AYItoUQDQgAEJg19rra1BeuYx9ZU1GbfD0ceE9X67/c2hdb6XZLQor5oNVa+o9HZ
WBioc1hNCC2avO1Dpg5ZAb2YsS71TT7Bsw==
-----END EC PRIVATE KEY-----

OpenSSL 根据SM2私钥生成公钥

openssl ec -in sm2_ec.key -pubout -out sm2_ec.pubkey 
read EC key
writing EC key
cat sm2_ec.pubkey 
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEJg19rra1BeuYx9ZU1GbfD0ceE9X6
7/c2hdb6XZLQor5oNVa+o9HZWBioc1hNCC2avO1Dpg5ZAb2YsS71TT7Bsw==
-----END PUBLIC KEY-----

OpenSSL SM3 计算文件Hash

echo "https://const.net.cn" > sign.data 
openssl dgst -SM3 sign.data 
SM3(sign.data)= 8c13610aeb3040b2899ac224ae7db0710030803c424f776e7241340c66a6d553

OpenSSL 使用 SM2 签名文件

openssl dgst -SM3 -sign sm2_ec.key -out sm2_ec.sig sign.data 
Error setting context
140524048778560:error:100C508A:elliptic curve routines:pkey_ec_ctrl:invalid digest type:../crypto/ec/ec_pmeth.c:331:

在当前版本(OpenSSL 1.1.1f)还不支持命令行使用SM2结合SM3签名。将hash算法换成sha256试试。
OpenSSL 使用 SM2 结合 sha256签名

openssl dgst -sha256 -sign sm2_ec.key -out sm2_ec.sig sign.data 
root@hesy-ThinkPad-P15v-Gen-1:/home/hesy/2021/asn1/src/sm# hexdump -C sm2_ec.sig 
00000000  30 46 02 21 00 d7 52 c2  63 a3 12 ff ef af 69 8e  |0F.!..R.c.....i.|
00000010  8a 35 17 9f f2 0c e2 b1  80 fb dd a1 38 a3 59 14  |.5..........8.Y.|
00000020  5a 18 33 ba 43 02 21 00  9d 10 91 a7 5f a4 cf bb  |Z.3.C.!....._...|
00000030  7b 75 c0 27 17 d5 2d 55  09 cc 10 49 29 f8 bc 0d  |{u.'..-U...I)...|
00000040  10 d6 02 db b1 e4 7c 7a                           |......|z|
00000048

OpenSSL 使用 SM2 结合 sha256 验签

openssl dgst -sha256 -verify sm2_ec.pubkey -signature sm2_ec.sig sign.data 
Verified OK

OpenSSL 使用 SM2 结合 SM3 验签

openssl dgst -SM3 -verify sm2_ec.pubkey -signature sm2_ec.sig sign.data 
Error setting context
140471948707136:error:100C508A:elliptic curve routines:pkey_ec_ctrl:invalid digest type:../crypto/ec/ec_pmeth.c:331:

同上面一样的原因,官方没实现,命令行用不了。

在golang中使用cgo调用openssl库的md5方法,最简单的方法

package main

/*
#cgo CFLAGS: -I ./include
#cgo LDFLAGS: -L ./lib -lcrypto
#include <stdlib.h>
#include <openssl/md5.h>
*/
import "C"

import (
    "encoding/hex"
    "fmt"
    "strings"
    "unsafe"
)

func main() {

    fmt.Println("go openssl md5 demo.")
    data := []byte("const.net.cn")
    md := make([]byte, 16)
    C.MD5((*C.uchar)(unsafe.Pointer(&data[0])), C.size_t(len(data)), (*C.uchar)(unsafe.Pointer(&md[0])))
    md5Str := hex.EncodeToString(md)
    md5Str = strings.ToUpper(md5Str)
    fmt.Printf("md5Str = %s\n", md5Str)
}

输出:

go run .
go openssl md5 demo.
md5Str = FA8424A7B72EB90BF04685205ECC5760
echo -n "const.net.cn" | md5sum 
fa8424a7b72eb90bf04685205ecc5760  -

在golang中使用cgo调用openssl库的md5方法,使用MD5_Init, MD5_Update, MD5_Final.

package main

/*
#cgo CFLAGS: -I ./include
#cgo LDFLAGS: -L ./lib -lcrypto
#include <stdlib.h>
#include <openssl/md5.h>
*/
import "C"

import (
    "encoding/hex"
    "fmt"
    "strings"
    "unsafe"
)

func main() {
    var ctx C.MD5_CTX
    C.MD5_Init(&ctx)
    data := []byte("https://const.net.cn")
    C.MD5_Update(&ctx, unsafe.Pointer(&data[0]), C.size_t(len(data)))
    md := make([]byte, 16)
    C.MD5_Final((*C.uchar)(unsafe.Pointer(&md[0])), &ctx)
    md5Str := hex.EncodeToString(md)
    md5Str = strings.ToUpper(md5Str)
    fmt.Printf("md5Str = %s\n", md5Str)
}

输出:

go run .
md5Str = 682D2C63236AF6E721794B2988FC1D44
echo -n "https://const.net.cn" | md5sum 
682d2c63236af6e721794b2988fc1d44  -