OpenSSL has a generic function PEM_write_PKCS8PrivateKey
that is capable of writing EVP_PKEY
keys to a PKCS8 structure in PEM format. In order to leverage that, you would have to wrap your DH key like this, with the error checking omitted for the sake of brevity:
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_PKEY_set1_DH(pkey, privkey);
PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL);
PKCS8 allows you to encrypt the contents, those trailing parameters that I did not set in that call are for setting the encryption details. I omitted them here, but you typically do want your private key material stored encrypted in practice.
Trying it out (after removing your BIO_dump_fp
call):
> dh_key
-----BEGIN PRIVATE KEY-----
MIICZAIBADCCAjkGByqGSM4+AgEwggIsAoIBAQCHqOYdtLZmPP+70ZxlGVmZjO72
CGYN0PJdLO7UQ147AOAN+PHWGVfU+vffRWGyqjAWw9kRNAlvqjv0KW2DDpp8IJ4M
ZJdRer1aip0wa89n7ZH55nJbR1jAIuCx70J1v3tsW/wR1F+QiLlB9U6x5Zu4vDmg
vxIwf1xP23DFgbI/drY6yuHKpreQLVJSZzVIig7xPG2aUb+kqzrYNHeWUk2O9qFn
taQYJdln4UTlFAVkJRzKy4PmtIb2s8o/eXFQYCbAuFf2iZYoVt7UAQq9C+Yhw6OW
ClTnEMN18mN11wFBA6S1QzDBmK8SYRbSJ24RcV9pOHf61+8JytsJSukeGhWXAoIB
AD+zLJtzE00LLndQZmDtvUhMp7GPIe8gVAf0eToaC6ElENvBUHe+Rj//T+1KrAu1
Vb46bBsMa0exvDdzv36Mb2KQEij4woy7GKVa4xNBAAplAZb5Mcd6V/Ld9GPl6ewU
S3d95iqquKhiisN20oLW7Thk5nmCQo68gx0UNI9vL5GTtQRa8nZxZOHfyWfB+z8u
VaS9G//oO5yA0FK5hdGC6grbKjtzE9P+FMhISx4FJYi5t9K70t8BYZns0G4VV80J
FbM1O7tk4Ow3f9AoNw35K1LHiRQozcZ+thhLUj0dskbDL2MHhJDwDvjWR9FI1HlU
UV4jJ8/vmMWCZktMD2zEFlkCIQCM+DZCpwmgl7RHmXZAEp2imbGkfR6zdQujCLD+
ZPX70wQiAiBvWQZVf0vXQPl+ovrzFwbia4oDGbPwYtQ83yaLtFo0hw==
-----END PRIVATE KEY-----
shows the PEM output. Piping it through asn1parse
shows its contents:
> dh_key | openssl asn1parse
0:d=0 hl=4 l= 612 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=4 l= 569 cons: SEQUENCE
11:d=2 hl=2 l= 7 prim: OBJECT :X9.42 DH
20:d=2 hl=4 l= 556 cons: SEQUENCE
24:d=3 hl=4 l= 257 prim: INTEGER :87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597
285:d=3 hl=4 l= 256 prim: INTEGER :3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659
545:d=3 hl=2 l= 33 prim: INTEGER :8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3
580:d=1 hl=2 l= 34 prim: OCTET STRING [HEX DUMP]:0220537AF1D957AB4D23D3779A22F2DD20F3330A0179DCF50AE922491EFB08976517
This actually includes the parameters as well.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…