【go语言】RSA加解密

关于go语言的RSA加解密的介绍,这里有一篇文章,已经介绍的很完整了。

对应的go语言的加解密代码,参考git

因为原文跨语言是跟php,我这里要跟c语言进行交互,所以,这里贴上c语言的例子。

参考原文:http://hayageek.com/rsa-encryption-decryption-openssl-c/

#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/buffer.h>

#include <stdio.h>
#include <stdint.h>


//编译
//gcc rsa_example.c -o example -L/usr/local/Cellar/openssl/1.0.2e/lib/ -lssl -lcrypto

//openssl的base64编解码: https://gist.github.com/barrysteyn/7308212
int Base64Encode(const unsigned char* buffer, size_t length, char** b64text) { 
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); 
    BIO_write(bio, buffer, length);
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    BIO_set_close(bio, BIO_NOCLOSE);
    BIO_free_all(bio);

    *b64text=(*bufferPtr).data;

    return (0); //success
}

int padding = RSA_PKCS1_PADDING;
 
RSA * createRSA(unsigned char * key,int public)
{
    RSA *rsa= NULL;
    BIO *keybio ;
    keybio = BIO_new_mem_buf(key, -1);
    if (keybio==NULL)
    {
        printf( "Failed to create key BIO");
        return 0;
    }
    if(public)
    {
        rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
    }
    else
    {
        rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
    }
    if(rsa == NULL)
    {
        printf( "Failed to create RSA");
    }
 
    return rsa;
}
 
int public_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted)
{
    RSA * rsa = createRSA(key,1);
    int result = RSA_public_encrypt(data_len,data,encrypted,rsa,padding);
    return result;
}
int private_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted)
{
    RSA * rsa = createRSA(key,0);
    int  result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);
    return result;
}
 
 
int private_encrypt(unsigned char * data,int data_len,unsigned char * key, unsigned char *encrypted)
{
    RSA * rsa = createRSA(key,0);
    int result = RSA_private_encrypt(data_len,data,encrypted,rsa,padding);
    return result;
}
int public_decrypt(unsigned char * enc_data,int data_len,unsigned char * key, unsigned char *decrypted)
{
    RSA * rsa = createRSA(key,1);
    int  result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);
    return result;
}
 
void printLastError(char *msg)
{
    char * err = malloc(130);;
    ERR_load_crypto_strings();
    ERR_error_string(ERR_get_error(), err);
    printf("%s ERROR: %s\n",msg, err);
    free(err);
}
 
int main(){
 
 char plainText[2048/8] = "1024"; //原始数据为字符串1024;key length : 2048, 数据最长为 keylen/8个char
 
 char publicKey[]="-----BEGIN PUBLIC KEY-----\n"\
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n"\
"ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n"\
"vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n"\
"fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n"\
"i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n"\
"PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n"\
"wQIDAQAB\n"\
"-----END PUBLIC KEY-----\n";
  
 char privateKey[]="-----BEGIN RSA PRIVATE KEY-----\n"\
"MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"\
"vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9\n"\
"Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9\n"\
"yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l\n"\
"WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q\n"\
"gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8\n"\
"omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e\n"\
"N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG\n"\
"X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd\n"\
"gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl\n"\
"vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF\n"\
"1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu\n"\
"m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ\n"\
"uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D\n"\
"JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D\n"\
"4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV\n"\
"WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5\n"\
"nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG\n"\
"PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA\n"\
"SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1\n"\
"I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96\n"\
"ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF\n"\
"yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5\n"\
"w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX\n"\
"uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw\n"\
"-----END RSA PRIVATE KEY-----\n";
 
    
unsigned char  encrypted[4098]={};
unsigned char decrypted[4098]={};
 
int encrypted_length= public_encrypt(plainText,strlen(plainText),publicKey,encrypted);
if(encrypted_length == -1)
{
    printLastError("Public Encrypt failed ");
    exit(0);
}
printf("Encrypted length =%d\n",encrypted_length);

char *b64text;

Base64Encode( encrypted, encrypted_length, &b64text);
printf("Base64Encode = %s\n", b64text);


int decrypted_length = private_decrypt(encrypted,encrypted_length,privateKey, decrypted);
if(decrypted_length == -1)
{
    printLastError("Private Decrypt failed ");
    exit(0);
}
printf("Decrypted Text =%s\n",decrypted);
printf("Decrypted Length =%d\n",decrypted_length);
 
 
encrypted_length= private_encrypt(plainText,strlen(plainText),privateKey,encrypted);
if(encrypted_length == -1)
{
    printLastError("Private Encrypt failed");
    exit(0);
}
printf("Encrypted length =%d\n",encrypted_length);
 
decrypted_length = public_decrypt(encrypted,encrypted_length,publicKey, decrypted);
if(decrypted_length == -1)
{
    printLastError("Public Decrypt failed");
    exit(0);
}
printf("Decrypted Text =%s\n",decrypted);
printf("Decrypted Length =%d\n",decrypted_length);
 
}

编译执行之后,可以得到加密之后的base64数据:

./example
Encrypted length =256
Base64Encode = BXFuS6snRRhYUQhTYKG00UoGMzaptbZpaw7h+JEA+yP1sEd5dXaBEjdzzZ8jXRVfjigYFj41zEBSDsafxO440+vi/aODOAY1f4Q2dKf5eBLnXDyN9uT6uxCp67XgZC3YkN+iufMOKIEjSbb361kZrRLwl+6OUt4EYvkhmKl5YpklM+qQYyGW5xyCU5MYMUTXJoAthRTeNuoloSiZDQWKPH4i7bVfR/XDjXIA3iNWfoy5552L4AdtyRhRNvZ0RerbVtPqdWABvJX39hbskmGuzY9HtoxOQaoD0IWGHx29VmCM3JRrTvStnEKjYnUNT9ikbeK1gXX5JjU6HmLHbgPKUg==
Decrypted Text =1024
Decrypted Length =4
Encrypted length =256
Decrypted Text =1024
Decrypted Length =4

把base64数据,传递给go语言(这里需要把对应的go语言的公钥、私钥替换成c语言中的示例),用私钥进行解密,可以得到对应的原始数据,这样验证 c 和 go之间的加解密OK。

go run rsa.go -d BXFuS6snRRhYUQhTYKG00UoGMzaptbZpaw7h+JEA+yP1sEd5dXaBEjdzzZ8jXRVfjigYFj41zEBSDsafxO440+vi/aODOAY1f4Q2dKf5eBLnXDyN9uT6uxCp67XgZC3YkN+iufMOKIEjSbb361kZrRLwl+6OUt4EYvkhmKl5YpklM+qQYyGW5xyCU5MYMUTXJoAthRTeNuoloSiZDQWKPH4i7bVfR/XDjXIA3iNWfoy5552L4AdtyRhRNvZ0RerbVtPqdWABvJX39hbskmGuzY9HtoxOQaoD0IWGHx29VmCM3JRrTvStnEKjYnUNT9ikbeK1gXX5JjU6HmLHbgPKUg==
[1024]

 

转载于:https://www.cnblogs.com/zhangqingping/p/5772297.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Go语言实现RSA加密解密的示例代码: ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" ) func main() { // 生成RSA密钥对 privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { panic(err) } // 将私钥编码为PEM格式 privatePem := pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), }) // 将公钥编码为PEM格式 publicPem, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) if err != nil { panic(err) } publicPemBlock := &pem.Block{ Type: "PUBLIC KEY", Bytes: publicPem, } publicPemBytes := pem.EncodeToMemory(publicPemBlock) // 显示密钥对 fmt.Println("Private Key:") fmt.Println(string(privatePem)) fmt.Println("Public Key:") fmt.Println(string(publicPemBytes)) // 加密明文 plaintext := []byte("Hello, world!") ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, &privateKey.PublicKey, plaintext) if err != nil { panic(err) } fmt.Println("Ciphertext:", ciphertext) // 解密密文 decrypted, err := privateKey.Decrypt(nil, ciphertext, &rsa.OAEPOptions{Hash: rsa.HashSHA256}) if err != nil { panic(err) } fmt.Println("Decrypted:", string(decrypted)) } ``` 在上述示例中,首先使用`rsa.GenerateKey()`函数生成了一个2048位的RSA密钥对。然后,使用`x509.MarshalPKCS1PrivateKey()`和`x509.MarshalPKIXPublicKey()`函数将私钥和公钥编码为PEM格式,并将它们打印出来。 接着,使用`rsa.EncryptPKCS1v15()`函数对明文进行加密,得到密文。使用私钥的`Decrypt()`方法对密文进行解密,得到原始的明文。 需要注意的是,在进行加密和解密时,需要使用不同的密钥。在本例中,使用公钥加密明文,然后使用私钥解密密文。如果使用私钥加密明文,那么只有对应的公钥才能解密密文。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值