GVKun编程网logo

如何在python中制作PKCS8 RSA签名(python rsa 签名)

20

如果您想了解如何在python中制作PKCS8RSA签名的相关知识,那么本文是一篇不可错过的文章,我们将对pythonrsa签名进行全面详尽的解释,并且为您提供关于AESECBPKCS5/PKCS7加

如果您想了解如何在python中制作PKCS8 RSA签名的相关知识,那么本文是一篇不可错过的文章,我们将对python rsa 签名进行全面详尽的解释,并且为您提供关于AES ECB PKCS5/PKCS7 加解密 python实现 支持中文、go RSA PKCS8、php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解、pkcs1与pkcs8格式RSA私钥互相转换的有价值的信息。

本文目录一览:

如何在python中制作PKCS8 RSA签名(python rsa 签名)

如何在python中制作PKCS8 RSA签名(python rsa 签名)

我有pkcs8_rsa_private_key文件,它是由openssl从rsa_private_key.pem文件生成的。

我需要使用python中的私钥进行签名,并使用以下Java代码进行相同的签名。

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";public static String sign(String content, String privateKey) {    String charset = "utf-8";    try {        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(                Base64.decode(privateKey));        KeyFactory keyf = KeyFactory.getInstance("RSA");        PrivateKey priKey = keyf.generatePrivate(priPKCS8);        java.security.Signature signature = java.security.Signature                .getInstance(SIGN_ALGORITHMS);        signature.initSign(priKey);        signature.update(content.getBytes(charset));        byte[] signed = signature.sign();        return Base64.encode(signed);    } catch (Exception e) {        e.printStackTrace();    }    return null;}

答案1

小编典典

PKCS#8定义了一种编码和传输秘密密钥的方法,并且它不是特定于OpenSSL的。PKCS#1定义了一种使用RSA密钥的方法(无论它如何以PKCS#8加载到您的应用程序中),以执行和验证数据的数字签名。

您拥有的这段代码可以完成三件事:

  1. 它将Base64解码为PKCS#8
  2. 它将PKCS#8解码为内存中的实际密钥(注意,您可能需要在此处提供密码)
  3. 它使用所述密钥使用SHA-1执行PKCS#1 v1.5签名
  4. 它在Base64中编码签名

在PyCrypto的API中进行PKCS#1
v1.5签名的示例完全执行了步骤2和步骤3。

AES ECB PKCS5/PKCS7 加解密 python实现 支持中文

AES ECB PKCS5/PKCS7 加解密 python实现 支持中文

[toc]

ECB模式介绍

电码本模式(Electronic Codebook Book (ECB) 这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。 在这里插入图片描述

pkcs5padding和pkcs7padding的区别

pkcs5padding和pkcs7padding都是用来填充数据的一种模式。在ECB中,数据是分块加密的。如果需要加密的数据的字节码的长度不是块大小的整数倍就需要填充。 使用PKCS5,填充时: 要填充7个字节,那么填入的值就是0×7; 如果只填充1个字节,那么填入的值就是0×1; 恰好8个字节时还要补8个字节的0×08 正是这种即使恰好是8个字节也需要再补充字节的规定,可以让解密的数据很确定无误的移除多余的字节。 PKCS7和PKCS5的区别是数据块的大小;

  • PKCS5填充块的大小为8bytes(64位)
  • PKCS7填充块的大小可以在1-255bytes之间。

因为AES并没有64位的块, 如果采用PKCS5, 那么实质上就是采用PKCS7

python实现

安装所需要的包

pip install pycryptodome

python代码

# -*- coding:utf-8 -*-
import base64
from Crypto.Cipher import AES


class EncryptDate:
    def __init__(self, key):
        self.key = key  # 初始化密钥
        self.length = AES.block_size  # 初始化数据块大小
        self.aes = AES.new(self.key, AES.MODE_ECB)  # 初始化AES,ECB模式的实例
        # 截断函数,去除填充的字符
        self.unpad = lambda date: date[0:-ord(date[-1])]      

    def pad(self, text):
        """
        #填充函数,使被加密数据的字节码长度是block_size的整数倍
        """
        count = len(text.encode(''utf-8''))
        add = self.length - (count % self.length)
        entext = text + (chr(add) * add)
        return entext

    def encrypt(self, encrData):  # 加密函数
        res = self.aes.encrypt(self.pad(encrData).encode("utf8"))
        msg = str(base64.b64encode(res), encoding="utf8")
        return msg

    def decrypt(self, decrData):  # 解密函数
        res = base64.decodebytes(decrData.encode("utf8"))
        msg = self.aes.decrypt(res).decode("utf8")
        return self.unpad(msg)


eg = EncryptDate("iiiioooojjjjpppp")  # 这里密钥的长度必须是16的倍数
res = eg.encrypt("中文测试!")
print(res)
print(eg.decrypt(res))

运行效果 在这里插入图片描述 可点击这里在线加解密,验证一下 在这里插入图片描述

注意事项

  1. 选择安装pycryptodome而不是pycrypto(安装pycrypto在python的某些版本会报错)
  2. 加密中文需要加密的是字节码而不是字符串(encode一下)
  3. pad函数中计算长度的时候计算的也是转换成字节码后的长度而不是字符串的长度
  4. 注意Linux下的换行符是\n,Windows下的换行符是\r\n(跨平台传输加密后的文件,在写入时需要注意)

go RSA PKCS8

go RSA PKCS8

RAS在线生成:http://www.metools.info/code/c80.html

PKCS#8 类型

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
)

var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAM8UxlNEntcW3ISGpzCuUFSIu/vkzo36
gDO7ZXri6CpyLwlKZ3GT/6j/CgR6JRpZYS3HxB2ykO1kfi6DKldkvPcCAwEAAQ==
-----END PUBLIC KEY-----

`)

var privateKey = []byte(`
-----BEGIN PRIVATE KEY-----
MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAzxTGU0Se1xbchIan
MK5QVIi7++TOjfqAM7tleuLoKnIvCUpncZP/qP8KBHolGllhLcfEHbKQ7WR+LoMq
V2S89wIDAQABAkA3B8ZMiofLkP+5GC+F+EzQqiWKoxthD5jSJpKpPXOFE6ib1u4M
u9/5CzgpDi2R+75skCb+g+uWtrGVFm2dbfPBAiEA59EPqb8Iq6NIbKAeAC2g+LRw
j0dy0JvkW6P5ntjG1L0CIQDkrx9ugORG5a5dmAH4eN81MuxhMGZojiUdE4hyY/0F
wwIgZbchvEWKNGWM3bzT7RgYTYg+619aTZZZeKxWVxCfDbECIE995GIoIbHXUxYr
qbuyYHyAmBRsm5yKlLIXwR1qTmC7AiAqD7kc2TqtKuCL/4Uxr/9m+4Z/UmamPaUe
KhtsmatceQ==
-----END PRIVATE KEY-----

`)

func main() {
	data, err := RsaEncrypt([]byte("Demo\n1611310969\n24212"))
	if err != nil {
		panic(err)
	}
	fmt.Println("加密数据:",base64.StdEncoding.EncodeToString(data))

	origData, err := RsaDecrypt(data)
	if err != nil {
		panic(err)
	}
	fmt.Println("解密数据:",string(origData))
}

// 加密
func RsaEncrypt(origData []byte) ([]byte, error) {
	block, _ := pem.Decode(publicKey)
	if block == nil {
		return nil, errors.New("public key error")
	}
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

//解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
	block, _ := pem.Decode(privateKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	parseResult, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, errors.New("parse error!")
	}
	priv := parseResult.(*rsa.PrivateKey)
	return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}

php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解

php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解

由于http请求是无状态,所以我们不知道请求方到底是谁。于是就诞生了签名,接收方和请求方协商一种签名方式进行验证,来取得互相信任,进行下一步业务逻辑交流。

其中签名用得很多的就是公钥私钥,用私钥签名,公钥验签,或者公钥加密,私钥解密。

不管是公钥和私钥,我们首先要进行格式化,当然如果你获取的就是格式化后的可忽略这一步

1、公钥私钥的格式化

********************私钥格式化********************/

function formatPriKey($priKey) {
    $fKey = "-----BEGIN PRIVATE KEY-----\n";
    $len = strlen($priKey);
    for($i = 0; $i < $len; ) {
        $fKey = $fKey . substr($priKey, $i, 64) . "\n";
        $i += 64;
    }
    $fKey .= "-----END PRIVATE KEY-----";
    return $fKey;
}
/********************公钥格式化********************/
function formatPubKey($pubKey) {
    $fKey = "-----BEGIN PUBLIC KEY-----\n";
    $len = strlen($pubKey);
    for($i = 0; $i < $len; ) {
        $fKey = $fKey . substr($pubKey, $i, 64) . "\n";
        $i += 64;
    }
    $fKey .= "-----END PUBLIC KEY-----";
    return $fKey;
}

格式化也就是加上前后缀,然后每64位进行换行,还可如下简单格式化:

//私钥格式化
$fKey = "-----BEGIN PRIVATE KEY-----\n".chunk_split($public_key, 64,"\n").''-----END PRIVATE KEY-----'';

//公钥格式化
$fKey = "-----BEGIN PUBLIC KEY-----\n".chunk_split($public_key, 64,"\n").''-----END PUBLIC KEY-----'';

2、私钥签名和公钥验签(SHA1withRSA)

/********************私钥签名********************/
function get_private_sign($sign_str,$private_key,$signature_alg=OPENSSL_ALGO_SHA1){
    $private_key = openssl_pkey_get_private(private_key);//加载密钥
    openssl_sign($sign_str,$signature,$private_key,$signature_alg);//生成签名
    $signature = base64_encode($signature);
    openssl_free_key($private_key);
    return $signature;
}
/********************公钥验签********************/
function public_verify($sign_str,$sign,$public_key,$signature_alg=OPENSSL_ALGO_SHA1){
    $public_key = openssl_get_publickey($public_key);
    $verify = openssl_verify($sign_str, base64_decode($sign), $public_key, $signature_alg);
    openssl_free_key($public_key);
    return $verify==1;//false or true
}

$sign_str为签名字符串或者验签字符串,$sign为签名,公钥私钥都必须是格式化后的,否则会无法识别。

3、公钥加密和私钥解密(SHA1withRSA)

/********************公钥加密********************/
function get_public_sign($sign_str,$public_key,$signature_alg=OPENSSL_ALGO_SHA1){
    $public_key = openssl_pkey_get_public($public_key);//加载密钥
    openssl_sign($sign_str,$signature,$public_key,$signature_alg);//生成签名
    $signature = base64_encode($signature);
    openssl_free_key($public);
    return $signature;
}

/********************私钥解密********************/
 function private_verify($sign_str,$sign,$private_key,$signature_alg=OPENSSL_ALGO_SHA1){
    $private_key = openssl_get_privatekey($private_key);
    $verify = openssl_verify($sign_str, base64_decode($sign), $private_key, $signature_alg);
    openssl_free_key($private_key);
    return $verify==1;//false or true
}

 4、AES(AES/ECB/PKCS5Padding)加密解密

//aes加密
function encrypt($data, $key) {
    $data =  openssl_encrypt($data, ''aes-128-ecb'', base64_decode($key), OPENSSL_RAW_DATA);
    return base64_encode($data);
}
//aes解密
function decrypt($data, $key) {
     $encrypted = base64_decode($data);
     return openssl_decrypt($encrypted, ''aes-128-ecb'', base64_decode($key), OPENSSL_RAW_DATA);
 }

 

pkcs1与pkcs8格式RSA私钥互相转换

pkcs1与pkcs8格式RSA私钥互相转换

1、PKCS1私钥生成

     openssl genrsa -out private.key 1024

     private.key文件内容如下:

     -----BEGIN RSA PRIVATE KEY-----
     MIICXQIBAAKBgQDREk3uy4x9i4a16OYOYEp5Ir2f16lsmUHB2HjGDlxkU0ju9YAp
     yeZlUXb191ZkxJ2vx2+vKppN4gKLDy5r7JMTpwch1CNvceySX6DiM4lwTAnUEZiB
     YgNBNrKINEtJmXWSZBTeR7v7HH/ExNP5vyhhk06L1lOoknhYcq99FjTGhwIDAQAB
     AoGABOtPVh0H8zRDOSh/sTrmxa7hk085t0pr16nGPbK8zcd/4c948oLDnwKpr+Pf
     7oMJyscAg7iW5No6gRccWoG4fCT5jBvJzcMloZnA36sE0btzlTj//714oBYiEcO4
     aWC7JByMgVWZ2WakqLQGoiv4oKdzizgc0LmCC3XM5+F+RpECQQD4yHQJuJd6/jgX
     IE8v83AiUJDh0N8nOt2SGqWzZpYKM1OUQIV+ss3SkRz5yWqfUBKgyU8OVkRWj78R
     uZi2WsijAkEA1yLwo+prkBm5rgbQIGRnDJ5Bbf/0/p+fSJfm2tiQ1o94TjuhJs49
     ehFLtJKpQT93xlOnFwI7rAJWVUdLPUs0zQJAL46iH/mZe3l9X25dtNzkYqrkB0bW
     YblvAa72XgUOSYTmRUDQRBgKIGZ9E4LdTvcPmIzi/+qdxa5U6B6Cgtl34QJBAIqU
     zz5HexJP//PCH7897cOLDcq13jNGz2wLrYG7j1EnCfAbKSu+HovLKGEhODX3lEgF
     CtUfcyDSQJqeWjEZiOECQQC9vagG0+dxLmvlXg6sYEN1c+eI8KJIapKg0XBzPAqY
     cfT2chF3dUPA3oTfrk51MbHaGjI1Ukd76Vp2Q83JClbp
     -----END RSA PRIVATE KEY-----

 

2、PKCS1私钥转换为PKCS8(该格式一般Java调用)

    openssl pkcs8 -topk8 -inform PEM -in private.key -outform pem -nocrypt -out pkcs8.pem

     pkcs8.pem文件内容

     -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANESTe7LjH2LhrXo
    5g5gSnkivZ/XqWyZQcHYeMYOXGRTSO71gCnJ5mVRdvX3VmTEna/Hb68qmk3iAosP
    LmvskxOnByHUI29x7JJfoOIziXBMCdQRmIFiA0E2sog0S0mZdZJkFN5Hu/scf8TE
    0/m/KGGTTovWU6iSeFhyr30WNMaHAgMBAAECgYAE609WHQfzNEM5KH+xOubFruGT
    Tzm3SmvXqcY9srzNx3/hz3jygsOfAqmv49/ugwnKxwCDuJbk2jqBFxxagbh8JPmM
    G8nNwyWhmcDfqwTRu3OVOP//vXigFiIRw7hpYLskHIyBVZnZZqSotAaiK/igp3OL
    OBzQuYILdczn4X5GkQJBAPjIdAm4l3r+OBcgTy/zcCJQkOHQ3yc63ZIapbNmlgoz
    U5RAhX6yzdKRHPnJap9QEqDJTw5WRFaPvxG5mLZayKMCQQDXIvCj6muQGbmuBtAg
    ZGcMnkFt//T+n59Il+ba2JDWj3hOO6Emzj16EUu0kqlBP3fGU6cXAjusAlZVR0s9
    SzTNAkAvjqIf+Zl7eX1fbl203ORiquQHRtZhuW8BrvZeBQ5JhOZFQNBEGAogZn0T
    gt1O9w+YjOL/6p3FrlToHoKC2XfhAkEAipTPPkd7Ek//88Ifvz3tw4sNyrXeM0bP
    bAutgbuPUScJ8BspK74ei8soYSE4NfeUSAUK1R9zINJAmp5aMRmI4QJBAL29qAbT
    53Eua+VeDqxgQ3Vz54jwokhqkqDRcHM8Cphx9PZyEXd1Q8DehN+uTnUxsdoaMjVS
    R3vpWnZDzckKVuk=
    -----END PRIVATE KEY-----

3、PKCS8格式私钥转换为PKCS1(传统私钥格式)

     openssl pkcs8 -in pkcs8.pem -nocrypt -out pri_key.pem

     pri_key.pem文件内容如下:

     -----BEGIN RSA PRIVATE KEY-----
     MIICXQIBAAKBgQDREk3uy4x9i4a16OYOYEp5Ir2f16lsmUHB2HjGDlxkU0ju9YAp
     yeZlUXb191ZkxJ2vx2+vKppN4gKLDy5r7JMTpwch1CNvceySX6DiM4lwTAnUEZiB
     YgNBNrKINEtJmXWSZBTeR7v7HH/ExNP5vyhhk06L1lOoknhYcq99FjTGhwIDAQAB
     AoGABOtPVh0H8zRDOSh/sTrmxa7hk085t0pr16nGPbK8zcd/4c948oLDnwKpr+Pf
     7oMJyscAg7iW5No6gRccWoG4fCT5jBvJzcMloZnA36sE0btzlTj//714oBYiEcO4
     aWC7JByMgVWZ2WakqLQGoiv4oKdzizgc0LmCC3XM5+F+RpECQQD4yHQJuJd6/jgX
     IE8v83AiUJDh0N8nOt2SGqWzZpYKM1OUQIV+ss3SkRz5yWqfUBKgyU8OVkRWj78R
     uZi2WsijAkEA1yLwo+prkBm5rgbQIGRnDJ5Bbf/0/p+fSJfm2tiQ1o94TjuhJs49
     ehFLtJKpQT93xlOnFwI7rAJWVUdLPUs0zQJAL46iH/mZe3l9X25dtNzkYqrkB0bW
     YblvAa72XgUOSYTmRUDQRBgKIGZ9E4LdTvcPmIzi/+qdxa5U6B6Cgtl34QJBAIqU
     zz5HexJP//PCH7897cOLDcq13jNGz2wLrYG7j1EnCfAbKSu+HovLKGEhODX3lEgF
     CtUfcyDSQJqeWjEZiOECQQC9vagG0+dxLmvlXg6sYEN1c+eI8KJIapKg0XBzPAqY
     cfT2chF3dUPA3oTfrk51MbHaGjI1Ukd76Vp2Q83JClbp
     -----END RSA PRIVATE KEY-----

我们今天的关于如何在python中制作PKCS8 RSA签名python rsa 签名的分享已经告一段落,感谢您的关注,如果您想了解更多关于AES ECB PKCS5/PKCS7 加解密 python实现 支持中文、go RSA PKCS8、php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解、pkcs1与pkcs8格式RSA私钥互相转换的相关信息,请在本站查询。

本文标签: