22.openssl程式設計——PEM格式
阿新 • • 發佈:2019-02-02
22.1 PEM概述
openssl使用PEM(Privacy Enhanced Mail)格式來存放各種資訊,他是openssl預設採用資訊方式。openssl中PEM檔案一般包含如下資訊:
a.內容型別
表明本檔案存放的是什麼資訊內容,他的形式為"---------------BEGIN XXXX-------------------",與結尾的"-----------------END XXXX---------------------------------"對應
b.標頭檔案
表明資料是如果被處理存放,Openssl中庸的最多的是加密資訊,比如加密演算法以及初始化向量iv.
c. 資訊體
為BASE64編碼的資料
舉例如下:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9CFD51EC6654FCC3
本例是作者生成的一個RSA金鑰,以PEM格式加密存放,採用了openssl預設的對稱加密演算法。
表明了
本檔案是一個RSA私鑰;
DES-EDE3-CBC對稱加密演算法
9CFD51EC6654FCC3 對稱演算法初始化向量iv.
22.2 openssl的PEM實現
openssl的PEM模組實現位於crypto/pem目錄下,並且還依賴於openssl的ASN1模組。
#define PEM_STRING_X509_OLD "X509_CERTIFICATE"
#define PEM_STRING_X509 "CERTIFICATE"
#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST"
#define PEM_STRING_X509_CRL "X509 CRL"
#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY"
#define PEM_STRING_PUBLIC "PUBLIC KEY"
#define PEM_STRING_RSA "RSA PRIVATE KEY"
#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY"
#define PEM_STRING_DSA "DSA PRIVATE KEY"
#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY"
#define PEM_STRING_PKCS7 "PKCS7"
#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY"
#define PEM_STRING_PKCS8INF "PRIVATE KEY"
#define PEM_STRING_DHPARAMS "DH PARAMETERS"
#define PEM_STRING_DHXPARAMS "X9.42 HD PARAMETERS"
#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS"
#define PEM_STRING_DSAPARAMS "DSA PARAMETERS"
#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
#define PEM_STRING_PARAMETERS "PARAMETERS"
#define PEM_STRING_CMS "CMS"
openssl生成PEM格式檔案的大致過程如下
a.將各種資料DER編碼
b,將a中的資料進行加密處理
c.根據型別以及是否加密,構造PEM頭
d.將b中的資料進行BASE64編碼,放入PEM檔案
備註:openssl各個型別的PEM函式處理主要是write和read函式。write函式用於生成PEM格式的檔案,而read函式主要用於讀取PEM格式的檔案。
22.3 PEM 函式
PEM函式定義在crypto/pem.h中
a.PEM_write_XXXX/PEM_write_bio_XXXXX
將XXXX代表的資訊型別寫入到檔案bio中
b.PEM_read_XXXX/PEM_read_bio_XXXX
從檔案bio中讀取PEM的XXXX代表型別的資訊。
XXXX可用代表的有:SSL_SESSION\X509\X509_REQ\X509_AUX\X509_CRL\RSAPrivateKEY\RSAPublicKey\DSAPrivateKey\PrivateKey\PKCS7\DHparams\NETSCAPE_CERT_SEQUENCE\PKCS8PrivateKey\DSAPrivateKey\dsa_pubkey\DSAparams\ECPKParameters\ECPrivteKey\EC_PUBKEY等
c. PEM_ASN1_read/PEM_ASN1_read_bio
低層的PEM讀取函式
d.PEM_ASN_write/PEM_ASN1_write_bio
底層PEM寫函式
e.PEM_read_bio
讀取PEM檔案各個部分,包括檔案型別、頭資訊以及訊息體(base64解碼後的結果)
f.PEM_get_EVP_CIPHER_INFO
根據頭資訊獲取對稱演算法,並載入初始化向量iv
g.PEM_do_header
根據對稱演算法,解密資料
h.PEM_bytes_read_bio
獲取PEM資料,得到的結果為一個DER編碼的明文資料,改函式先後呼叫e,f,g.h
23.3 Engine 資料結構
struct engine_st
{
const char *id;
const char *name;
const RSA_METHOD *rsa_meth;
const DSA_METHOD *dsa_meth;
const DH_METHOD *dh_meth;
const EC_KEY_METHOD *ec_meth;
const RAND_METHOD *rand_meth;
ENGINE_CIPHERS_PTR ciphers;
ENGINE_DIGESTS_PTR digests;
ENGINE_PKEY_METHS_PTR pkey_meths;
ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
ENGINE_GEN_INT_FUNC_PTR destroy;
ENGINE_GEN_INT_FUNC_PTR init;
ENGINE_GEN_INT_FUNC_PTR finish;
ENGINE_CTRL_FUNC_PTR ctrl;
ENGINE_LOAD_KEY_PTR load_privkey;
ENGINE_LOAD_KEY_PTR load_pubkey;
ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
const ENGINE_CMD_DEFN *cnd_defns;
int flags;
CRYPTO_REF_COUNT struct_ref;
int funct_ref;
CRYPTO_EX_DATA ex_data;
struct engine_st *prev;
struct engine_st *next;
}
本結構包含大量運算集合函式
id:Engine標識
name:Engine名字
rsa_meth: RSA方法集合
dsa_meth:DSA方法集合
dh_meth: DH方法集合
ecdh_meth: ECDH方法結合
ecdsa_meth:ECDSA方法集合
rand_meth:隨機數方法集合
store_meth:儲存方法集合
ciphers:對稱演算法選取。
digests:摘要演算法選取函式。該回調函式用來從使用者實現的多個摘要演算法中根據某種條件
destroy:銷燬引擎函式
init:初始化引擎函式
finish:完成回撥函式
ctrl:控制函式
load_privkey:載入私鑰函式
load_pubkey:載入公鑰函式
ex_data:擴充套件資料結構,可用來存放使用者資料
prev/next:用於構建Engine連結串列,openssl中的硬體Engine可能不止一個。
c.