RSA加密解密-数据无大小限制 golang PHP 两个版本

RSA加密解密-数据无大小限制 golang PHP 两个版本,第1张

说明

RSA加密的资料自行百度。都知道RSA加密对数据大小是有限制的,以下主要是实现 数据无大小限制
RSA一般有这两种加密方式OAEPP、PKCS
PKCS的padding就占用了11个字节,
OAEP的padding 就占用了42个字节。

下面贴代码

下面密钥不是正常的要测试请自己生成密钥

Go实现
package main

import (
	"bytes"
	"crypto/rand"
	orsa "crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"log"
)

// 私钥生成
//openssl genrsa -out rsa_private_key.pem 1024
const RsaPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC0YG4mBipsXt03Jshaianuil24jTs4R0dVoflQH2V6AkMjfDuk
KIFuYHnOZtXVLJanyPi5lreiCycU+OhiwWtEnbMulr2Ih+WVbfspZXnvUczFhLAR
jSlfrNlxXPCmr3Nn8BCSL3GCmThdxhTwMqFwLnUrMY/VQ7my6js3uKWNgQIDAQAB
AoGAQXJXpP5JuEZ3V4J/4bHfcYjM1qCP4yyhqmV502OA61MUzzRNY5O62rSwnX5c
iduC0mAuNxCDko0fYhGqJ+LsKz5EJVezmX3CEHGebU9LLOyxRr/CJI6wut4SRONV
3N6NcPCk115mvOKYQgmkdRlxlSrPQ+z7wTuCNLYbAb5rav0CQQDgR60G5YXc6JF7
ryvx2GUY2eRY4dOzekEp3wztYK6YLXRUHkCrySnG1YgT+sb12BFPGS31suHuGygY
ZOEAlZQzAkEAzeMu1tAFPWMIXSYYXoOZDySaIJE6eL7lVitbCp/5xBJgy4Xil3Rr
oEfOR3YrHJxtdLgrOQC5E+6zufNzewpDewJAYDRetCagVTIttbBeWU9Jjm9o0/eK
p+I5MYzMLsbaHczhqXOQqh+QHApcZLWdwrb8NcHHRS2GXGyptk0PdwCyoQJAOawn
1LiUnyt8jks7jE4ks9825WSJEoW2zDp82C8T0d6sCpbIcFCGTXGP0OjDDtKqvoVQ
ZjlTnsfAxJfzg0XOvQJAfgMb4Rwqdxqd9oiA/svV743T3Iu02Qxe1YdL0PU5Ckxj
KGq979nkcMBV8mHiqQHm0AufNdo7T5UvdjtZXV/7MA==
-----END RSA PRIVATE KEY-----`

// 公钥: 根据私钥生成
//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
const RsaPublicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3vdYGES6AOLC2nmHQvq9XRWFQ
puQo9ryH31TQn/j+pNf870D3c3HLeI9Y4ApfMq9N5eBZJCQtajrghlzKyI1L+mV4
2wGU4/j1EBEO1ZGUoSXrCNa9OJODFNis3plG95vRnYHneuDmDbxw9XzGWqzhckzj
mwxiGKkDpI80iepTpQIDAQAB
-----END PUBLIC KEY-----`

type Rsa struct {
	privateKey *orsa.PrivateKey
	publicKey  *orsa.PublicKey
}

var rsa Rsa

// 公钥加密
func (r *Rsa) Encrypt(origData string) (string, error) {
	partLen := r.publicKey.N.BitLen()/8 - 42
	chunks := r.split([]byte(origData), partLen)
	buffer := bytes.NewBufferString("")
	for _, chunk := range chunks {

		bytes_, err := orsa.EncryptOAEP(sha1.New(), rand.Reader, r.publicKey, chunk, []byte{})
		if err != nil {
			log.Println(len(chunk), r.publicKey.Size())
			return "", err
		}
		buffer.Write(bytes_)
	}
	return base64.RawURLEncoding.EncodeToString(buffer.Bytes()), nil
}

// 私钥解密
func (r *Rsa) Decrypt(encrypted string) (string, error) {
	partLen := r.publicKey.N.BitLen() / 8
	raw, err := base64.RawURLEncoding.DecodeString(encrypted)
	chunks := r.split(raw, partLen)
	buffer := bytes.NewBufferString("")
	for _, chunk := range chunks {
		decrypted, err := orsa.DecryptOAEP(sha1.New(), rand.Reader, r.privateKey, chunk, []byte{})
		if err != nil {
			return "", err
		}
		buffer.Write(decrypted)
	}
	return buffer.String(), err
}

func (r *Rsa) split(buf []byte, lim int) [][]byte {
	var chunk []byte
	chunks := make([][]byte, 0, len(buf)/lim+1)
	for len(buf) >= lim {
		chunk, buf = buf[:lim], buf[lim:]
		chunks = append(chunks, chunk)
	}
	if len(buf) > 0 {
		chunks = append(chunks, buf[:len(buf)])
	}
	return chunks
}

// 初始化密钥对
func init() {
	block, _ := pem.Decode([]byte(RsaPrivateKey))
	if block == nil {
		panic("private key error")
	}
	private, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}

	block, _ = pem.Decode([]byte(RsaPublicKey))
	if block == nil {
		panic("public Key error")
	}

	public, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	pub, ok := public.(*orsa.PublicKey)

	if !ok {
		panic("public key type error")
	}

	rsa = Rsa{
		privateKey: private,
		publicKey:  pub,
	}

}

PHP实现
$private_key = "-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALe91gYRLoA4sLae
YdC+r1dFYVCm5Cj2vIffVNCf+P6k1/zvQPdzcct4j1jgCl8yr03l4FkkJC1qOuCG
XMrIjUv6ZXjbAZTj+PUQEQ7VkZShJesI1r04k4MU2KxWmUb3m9Gdged64OYNvHD1
fMZarOFyTOObDGIYqQOkjzSJ6lOlAgMBAAECgYB3BzRZc9Hy4Eah1tI43v5Jg7l5
/NM7MjOJtYSFLcyocXM1+GvWoWOrUutRwLkXWIc16F/Af2gsP2/quT/tYaQd5LhQ
+vosqWjMcZq17fsGw9gkyM7EcXzGYUSuYqkGsGgZi9VgVgR41k2FVAjns0t6bKUs
hcWeLJO1RLUWOKcoAQJBAO9T4LAR36mP5ntbKggVjmVG/YjXHinKEVQxzVQH0u/F
BuO2ePC56cYyN6bYXSW00oZbx0RiHwzITCPPKdvyFgECQQDEiqWQfd28mXdLQNBQ
nHqYCeGMix8yq2qKXsR7fVXZKalKUGcGJYVlIGatz5rWgmFTYaPTMzawny25EUJR
tCWlAkEAqEGlFsP2dnBnztPh8fsNuGA3gQwT9bdNhY7Z1zkE8HLpjBBOaJecJi5J
9+/nVMoStEk0B/yf7cGn3gkYWbySAQJAI8lO/jE816Nl6kjh5VuoothhvjJyusol
ew5oXkfjAsioL4TWTXM1h8VPjORZQCe7SvBjYQhZM+236JOw7KmNlQJAC0/K2kAT
rSR/osOTsBzBrhEY42EjnDR4jV6PhHhmPRVsjqAiuW/AcETdYVSWp0nUN8KFZuRx
C4VI4949QATRnw==
-----END PRIVATE KEY-----";

$public_key = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQ33vdYGES6AOLC2nmHQvq9XRWFQ
puQo9ryH31TQn/j+pNf870D3c3HLeI9Y4ApfMq9N5eBZJCQtajrghlzKyI1L+mV4
2wGU4/j1EBEO1ZGUoSXrCNa9OJODFNisVplG95vRnYHneuDmDbxw9XzGWqzhckzj
mwxiGKkDpI80iepTpQIDAQAB
-----END PUBLIC KEY-----";

function url_safe_base64_decode($data)
{
    $base_64 = str_replace(array('-', '_'), array('+', '/'), $data);
    return base64_decode($base_64);
}

function url_safe_base64_encode($data)
{
    return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($data));
}

//私钥解密
function Decrypt($string, $private_key)
{
    $privateKey = openssl_get_privatekey($private_key);
    if (!$privateKey) {
        echo "Cannot get private key";
    }

    $encr = url_safe_base64_decode($string);
    $parts = str_split($encr, 128);


    foreach ($parts as $part) {
        $decrypted_temp = '';
        openssl_private_decrypt($part, $decrypted_temp, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
        $decrypted .= $decrypted_temp;
    }
    return $decrypted;
}

//公钥加密
function Encrypt($string, $public_key)
{
    $encrypted = '';
    $part_len = 128 - 42;
    $parts = str_split($string, $part_len);

    foreach ($parts as $part) {
        $encrypted_temp = '';
        openssl_public_encrypt($part, $encrypted_temp, $public_key, OPENSSL_PKCS1_OAEP_PADDING);
        $encrypted .= $encrypted_temp;
    }

    return url_safe_base64_encode($encrypted);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995444.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存