This is a creation in Article, where the information may have evolved or changed.
Reason
In connection with the third-party platform, there will usually be some signature or encryption processing, in the development of the time, because the language
, they need to be handled according to the specifications accordingly.
Des plus decryption
Des:https://en.wikipedia.org/wiki/data_encryption_standard
Golang in the standard library crypto/des in the implementation of DES, but the Golang library description is relatively simple, if not familiar with DES encryption rules, is not easy
Written in the corresponding code, and third-party encryption and decryption between different languages, it is also easy to confuse, error occurred.
Des is differentiated into CBC and EBC encryption modes, and has different padding methods.
CBC (ET): https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
Padding:https://en.wikipedia.org/wiki/padding_ (cryptography)
Note pkcs#5 padding is identical to pkcs#7 padding
So for different platforms and languages to the Des plus decryption docking, you need to know what encryption mode and what kind of filling method is used:
Windows defaults to CBC mode, the CryptSetKeyParam function, and the OpenSSL function name directly indicates
In Java if Cipher.getinstance () is not filled in, the default is Des/ecb/pkcs5padding
The default is CBC mode in C #, pkcs7padding (pkcs5padding)
Golang provides CBC mode by default, so you need to write your own code for the ECB mode
Pkcs5padding and Pkcs5unpadding
func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } func PKCS5Unpadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] }
ECB encryption mode
block, err := des.NewCipher(key) if err != nil { ... } bs := block.BlockSize() src = PKCS5Padding(src, bs) if len(src)%bs != 0 { .... } out := make([]byte, len(src)) dst := out for len(src) > 0 { block.Encrypt(dst, src[:bs]) src = src[bs:] dst = dst[bs:] } ... }
Decryption under the ECB
block, err := des.NewCipher(key) if err != nil { ... } out := make([]byte, len(src)) dst := out bs := block.BlockSize() if len(src)%bs != 0 { ... } for len(src) > 0 { block.Decrypt(dst, src[:bs]) src = src[bs:] dst = dst[bs:] } out = PKCS5UnPadding(out)
RSA Plus decryption
Unlike other languages, which have a more advanced package, the Golang needs to be packaged according to different concepts, and there are several different concepts that need to be understood first.
Pem:https://en.wikipedia.org/wiki/privacy-enhanced_electronic_mail, Typically, files ending in. Pem are used more in key storage and in the certificate system, and the following is a PEM format under a X509 certificate:
-----BEGIN CERTIFICATE----- base64-----END CERTIFICATE-----
PKCS:HTTPS://EN.WIKIPEDIA.ORG/WIKI/PKCS, this is a huge system, with different keys in different PKCS file formats. such as the private key using PKCS8.
x.509:https://en.wikipedia.org/wiki/x.509, which is a public key management base (PKI), usually corresponds to PKIX in the IETF.
Description
openssl genrsa -out rsa_private_key.pem 1024
PEM files that are generated using OpenSSL (such as) are in PEM format to -----BEGIN RSA PRIVATE KEY-----
begin with and -----END RSA PRIVATE KEY-----
end with.
can also be converted to PKCS8:
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
Note that although the data format is PKCS8 format,-outform also indicates that the file format is still in PEM format, except that there are two PEM files that are different.
Clear the above several concepts and formats, write Golang corresponding public key and private key encryption method, it is relatively easy, the first is to decode the Pem file, and then the corresponding password decoding to Golang support structure, and then the corresponding processing.
For the private key, you can sign the following actions:
block, _ := pem.Decode([]byte(key)) if block == nil { // 失败情况 .... } private, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { ... } h := crypto.Hash.New(crypto.SHA1) h.Write(data) hashed := h.Sum(nil) // 进行rsa加密签名 signedData, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), crypto.SHA1, hashed) ...
Decrypted by the private key, the code format is as follows;
block, _ := pem.Decode([]byte(key)) if block == nil { // 失败情况 .... } private, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { ... } v, err := rsa.DecryptPKCS1v15(rand.Reader, private, data) ...
Encrypt the data for the public key:
block, _ := pem.Decode([]byte(key)) if block == nil { // 失败情况 .... } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { ... } encryptedData, err := rsa.EncryptPKCS1v15(rand.Reader, pub.(*rsa.PublicKey), data) ...
Summary
Figure out the specific encryption method, and then write in the Golang, the code is still very clear and not ugly to understand.
Article published on https://segmentfault.com/a/1190000004151272, author: Damon