golang cgo实现公钥解密

//C语言封装:
// 文件 rsa.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "openssl/x509.h"
// base64解码
int base64_decode(char *src,unsigned char *dst)
{
    char *q=malloc(strlen(src)+1);
    char *p=dst;
    char *temp=q;
    char *s=src;
    int len=strlen(src),i;
    memset(q,0,strlen(src)+1);
    while(*s)
    {
        if(*s>='A'&&*s<='Z') *temp=*s-'A';
        else if(*s>='a'&&*s<='z') *temp=*s-'a'+26;
        else if(*s>='0'&&*s<='9') *temp=*s-'0'+52;
        else if(*s=='+') *temp=62;
        else if(*s=='/') *temp=63;
        else if(*s=='=') *temp=-1;
        else
        {
            return 1;
        }
        ++s;
        ++temp;
    }
    for(i=0;i<len-4;i+=4)
    {
        *p++=(*(q+i)<<2)+(*(q+i+1)>>4);
        *p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
        *p++=(*(q+i+2)<<6)+(*(q+i+3));
    }
    if(*(q+i+3)!=-1)
    {
        *p++=(*(q+i)<<2)+(*(q+i+1)>>4);
        *p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
        *p++=(*(q+i+2)<<6)+*(q+i+3);
    }
    else if(*(q+i+2)!=-1)
    {
        *p++=(*(q+i)<<2)+(*(q+i+1)>>4);
        *p++=(*(q+i+1)<<4)+(*(q+i+2)>>2);
        *p++=(*(q+i+2)<<6);
    }
    else if(*(q+i+1)!=-1)
    {
        *p++=(*(q+i)<<2)+(*(q+i+1)>>4);
        *p++=(*(q+i+1)<<4);
    }
    else
    {
        return 1;
    }
    *p=0;
    free(q);
    
    return 0;
}
// RSA 公钥解密
int DoPublicKeyDecryption(const unsigned char *key,int key_size,const unsigned char *from,int from_size,unsigned char *to,int to_size)
{
    int                        padding;
    int                        fsurlen,to_count,flen;
    int                        result;
    int                        i;
    const unsigned char    *ucp;
    unsigned char            *from_temp;
    unsigned char            *to_temp;
    RSA                        *rsa;
    
    ucp = key;
    rsa = d2i_RSA_PUBKEY(NULL, &ucp, key_size);
    if(NULL == rsa)
    {
        return 0;
    }
    
    padding = RSA_PKCS1_PADDING;
    flen = RSA_size(rsa);
    
    from_temp = (unsigned char*)malloc(flen);
    to_temp = (unsigned char*)malloc(flen);
    fsurlen = from_size;
    to_count = 0;
    
    for(i = 0; fsurlen > 0; i++)
    {
        memset(from_temp, 0x00, flen);
        memset(to_temp, 0x00, flen);
        memcpy(from_temp, &from[flen * i], flen);
        fsurlen -= flen;
        result = RSA_public_decrypt(flen, from_temp, to_temp, rsa, padding);
        if(-1 == result)
        {
            free(from_temp);
            free(to_temp);
            return 0;
        }
        
        memcpy(to + to_count, to_temp,result);
        to_count += result;
        if((to_count + result) > to_size)
        {
            free(from_temp);
            free(to_temp);
            return 0;
        }
    }
    
    free(from_temp);
    free(to_temp);
    return to_count;
}
// 公共Key
char* RSAPublicDecrypt(char *publickey, char *dem)
{
    //base64解码  key
    int lenKey = ((strlen(publickey)+2)*4/3)+1;
    unsigned char *puk = (unsigned char *)malloc(lenKey);
    memset(puk, 0x00, lenKey);
    if (base64_decode(publickey, puk) != 0)
    {
        return "";
    }
    
    //printf("depuk lenght: %lu\n",strlen(puk));
    
    //base64解码  密文
    int lenDem = ((strlen(dem)+2)*4/3)+1;
    unsigned char *de = (unsigned char *)malloc(lenDem);
    memset(de, 0x00, lenDem);
    if (base64_decode(dem, de) != 0)
    {
        return "";
    }
    
    //printf("depuk lenght: %lu\n",strlen(de));
    
    //解密
    unsigned int lenPlaintext = lenKey-11 + 1; //明文长度 <= 密钥长度 - 11
    unsigned char *plaintext = (unsigned char *)malloc(lenPlaintext);
    unsigned int txtlen;
    memset(plaintext, 0x00, lenPlaintext);
    txtlen = DoPublicKeyDecryption(puk, lenKey, de, lenDem, plaintext, lenPlaintext);
    
    free(puk);
    free(de);
    free(plaintext);
    
    return plaintext;
}
/*
int main()
{
    char *depuk =  "please input your publickey";
    char *dem = "please input your ciphertext";
    
    char *plaintext = RSAPublicDecrypt(depuk, dem);
    
    printf("Plaintext: %s\n", plaintext);
    
    return 1;
}*/


// 以下是golang 调用例子

// 文件 main.go
package main

// #include <stdlib.h>
// #include <string.h>
// #include "rsa.h"
// #cgo LDFLAGS: -lcrypto
import "C"
import (
	"fmt"
)

var publicKey = "please input your plublicKey"
var content = "please input your ciphertext"

func main() {
	// Decrypt
	plaintext := C.RSAPublicDecrypt(C.CString(publicKey), C.CString(content))
	plaintextStr := C.GoString(plaintext)
	if plaintextStr == "" {
		panic("RSA PublicKey Decrypt failed")
	}

	fmt.Println(fmt.Sprintf("plaintext:%s", plaintextStr))
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值