文档章节

go语言, 初识RSA加密

漂泊的树叶
 漂泊的树叶
发布于 2017/07/24 16:00
字数 733
阅读 134
收藏 1

简介:

    作为一名初学者,简单阅读了的RSA的加密原理,和几篇关于go语言rsa加密的博客,

写了一个很简陋的demo. 记录下来,以免忘记 

1.包含方法

    (1)公钥加密

    (2)私钥解密

    (3)私钥签名

    (4)公钥验签

    直接看代码

2.代码

2.1 加密代码

package util

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

/**
   @param sourceBytes 原文
   @param publicKey  公钥字符串
   公钥加密
 */
func EncipherRsa(sourceBytes []byte, publicKey string) ([]byte, error)  {
	//获取公钥
	block, _ := pem.Decode([]byte(publicKey))
	if block == nil {
		return nil, errors.New("获取公钥失败")
	}
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)
	//声明密文,动态数组
	var cipherByte []byte
	//分段加密
	for i := 0; i < len(sourceBytes); i += 245{
		var slice []byte
		if(i + 245) < len(sourceBytes){
			slice = sourceBytes[i : i + 245]
		}else {
			slice = sourceBytes[i : len(sourceBytes)]
		}
		//Rsa加密,encryptBytes:分段密文
		encryptBytes, err := rsa.EncryptPKCS1v15(rand.Reader, pub, slice)
		if err != nil {
			return nil, err
		}
		//追加分段密文encryptBytes=>cipherByte
		cipherByte = append(cipherByte, encryptBytes...)
	}
	return cipherByte,nil
}

/**
	@param cipherByte 密文
	@param privateKey 私钥字符串
  	私钥解密,返回原文
 */
func DecipherRsa(cipherByte []byte, privateKey string) ([]byte, error) {
	//获取私钥
	block, _ := pem.Decode([]byte(privateKey))
	if block == nil {
		return nil, errors.New("private key error!")
	}
	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	//声明一个动态数组,用来存放解密之后的数据
	var source []byte
	//分段解密
	for i :=0; i < len(cipherByte); i += 256{
		var slice []byte
		if(i + 256) < len(cipherByte){
			slice = cipherByte[i : i + 256]
		}else {
			slice = cipherByte[i : len(cipherByte)]
		}
		//rsa解密
		decrypt, err := rsa.DecryptPKCS1v15(rand.Reader, priv, slice)
		if err != nil{
			return nil, err
		}
		//追加解密数据decrypt=>source
		source = append(source, decrypt...)
	}
	return source, nil
}

/**
	@param cipherText  待签名字段
	RSA私钥签名sha1
 */
func RsaSign(cipherText []byte, privateKey string) ([]byte, error) {
	//获取私钥
	block, _ := pem.Decode([]byte(privateKey))
	if block == nil {
		return nil, errors.New("private key error!")
	}
	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	//指定HASH类型  SHA1
	h := crypto.Hash.New(crypto.SHA1)
	h.Write(cipherText)
	hashed := h.Sum(nil)
	//返回签名结果
	return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA1, hashed)
}

/**
	@param origData 待签名字段
	@param sign     签名
	公钥验签
 */
func VerifySign(origData []byte, sign []byte, publicKey string) error {
	//获取公钥
	block, _ := pem.Decode([]byte(publicKey))
	if block == nil {
		return errors.New("public key error")
	}
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return  err
	}
	pub := pubInterface.(*rsa.PublicKey)
	//指定HASH类型  SHA1
	h := crypto.Hash.New(crypto.SHA1)
	h.Write(origData)
	hashed := h.Sum(nil)
	//返回验签结果
	err = rsa.VerifyPKCS1v15(pub, crypto.SHA1, hashed, sign)
	return err
}

2.2测试代码

package main

import (
	"util"
	"log"
	"fmt"
)

var public_key = `
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs2fv0rclnSLCCoG+tUV
IbphXbpXBeugeLTRkYE2WSSfdk5m0oyPmg15fnaoj/yhEy9vmAVGrqA4ROa3Q5V
C6vWZZXGbsiUzyloHZ63IGylRdsfXt3Wlys9vkxUko4SDdZBIUe2fDCz2x/YRcw
idjchumGnAVxMpZx+WLgPZa+h537Iv993XYn2g7Y7WLSc6/lj0IdPws521Y3PbF
XQFb7jqHVgQKcavvqwpkRxb3wbK1+EDXVO4tiBNpE1MNjnkaaQX/ZKSi0GRBlTw
IJ3u1NSBfya/3rhvfgZQClFyn1IKaUcyWoy8qSxts6yujT0qR8cHnfSf4CB64Vn
CO+LQQMwIDAQAB
-----END PUBLIC KEY-----
`
var privateKey = `
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAs2fv0rclnSLCCoG+tUVIbphXbpXBeugeLTRkYE2WSSfdk5m
0oyPmg15fnaoj/yhEy9vmAVGrqA4ROa3Q5VC6vWZZXGbsiUzyloHZ63IGylRdsf
Xt3Wlys9vkxUko4SDdZBIUe2fDCz2x/YRcwidjchumGnAVxMpZx+WLgPZa+h537
Iv993XYn2g7Y7WLSc6/lj0IdPws521Y3PbFXQFb7jqHVgQKcavvqwpkRxb3wbK1
+EDXVO4tiBNpE1MNjnkaaQX/ZKSi0GRBlTwIJ3u1NSBfya/3rhvfgZQClFyn1IK
aUcyWoy8qSxts6yujT0qR8cHnfSf4CB64VnCO+LQQMwIDAQABAoIBAAka10L8ZH
5LC0n5N7J/Z6OlO5qzIvSX3yAwLn/ssBnaWhZpkI9O/R3hpjycK+OBKaym5k9e0
7VdsWYZ+iYJKND/5r0XxB1buFwHDwYx7UJLcc3cS0wXU+jo2f1hLx/tyQ6RFFUG
+RES+nuBQivgT920pYNl+NTZ6CCK9799wTQ8Tc72MR9zycTPDCND8GJfzJuChin
zNFTlP6B36uvtOFRhhDiQBRUi0u+MiyaoGfMGlLBN+cerCZncjUMGT/NuQaDMxJ
NZS0kuwQAb2FRoEiMokbZOlMr242RXSGUgq1amSMy0pFkj/h4Kn8auzW1UWBdLi
i9iL8V3VGgL3d14+WECgYEA5iOwpOuXO/MmCVVWEDbcdY3TEjOi3UUnjCKjf4If
LUi0F9rCtAcNMVc6gqF0TK0kg53q7pA8ziE3s+IgHaNWra+wMRB5L38uRt1BEku
aU7e4MvLuXHSNsQkpajrTJ3wxttPPCMoNFniGWDdIHTvso/NbnuH46sYFWGfcrB
Kg5JsCgYEAx5DSuIQGisUiQeNDpRM9fVj9nT4Cxp7rFvKzr3gLQ5zqmmyczfAXl
G1n60C1jlxnbRbb+7ruiuWxIl4HJL0+qvziPwC+uI2NP53mTIHLojQT51hZnPP/
6i5R6IUsfIyHu7Mka2H1VqEcaDDXqXitGUc9rw7qxKA5jsb+kpf2oEkCgYEA40x
ssvZcsEE+WAmIrwsAQrqItXl6acBbhvTPNqh10mv0M3tEwjoUtZ7JkyuTigeYAM
Z/uo+K/qugMHIt9hfVDEZxZoQ2rMqYEjWEh2VUT0stCmUVNwuGxkueM+VVl7H6B
/C6kpu8wWzYg1hWSUleN6+r1gipqHdb4Cz0rp7XefECgYAvIPdyldNJsFZvwvD1
qf6KfJqgKMXVDDCuobBnjuzyEbuhrma1h6654cB54TU/InlWXOCkqTeuW6IiYJx
FQ9/p14DCqjVgNiWWUX7SsJBbhPryVn4LP+A++KNlSxX/b9yaKis+pMqgo7mmrW
ow3ovafWWG0voEZ2ZQXpQ+IF8g6QKBgEVtcFiUdTz9jN6tbAQ7s9utvS3VBtQNO
doWVURLa0moLbgTgQlz2f5lsRkNiOulCYcPTfv1P9GsWhtrd9q1KNjUN87xR9vl
z25qLHCla5XzpgfsYIbnsq1Eew2ulzoDMrAxeiTEmLMxH5L+CojGDAoSKFgkfQE
3NKhDdtJCtqtg
-----END RSA PRIVATE KEY-----
`

func main()  {

	var str = "testrsa123"

	//公钥加密
	encryptBytes, err := util.EncipherRsa([]byte(str), public_key)
	if err != nil{
		log.Fatal(err)
	}

	//私钥解密
	decryptBytes, err := util.DecipherRsa(encryptBytes, privateKey)
	if err != nil{
		log.Fatal(err)
	}
	fmt.Println("解密结果=" + string(decryptBytes))

	//私钥签名
	signBytes, err := util.RsaSign([]byte(str), privateKey)
	if err!= nil{
		log.Fatal(err)
	}

	//公钥验签
	err = util.VerifySign([]byte(str), signBytes, public_key)
	if err == nil{
		fmt.Println("签名校验成功")
	}
}

 

© 著作权归作者所有

共有 人打赏支持
上一篇: golang 时间计算
下一篇: golang 时间计算
漂泊的树叶
粉丝 0
博文 2
码字总数 950
作品 0
杭州
程序员
私信 提问
java服务端、php、C#客户端rsa

最近公司项目需要用到rsa,故对rsa签名算法的一些概念和不同语言的使用进行了研究(具体实现算法则不钻牛角尖了) 对rsa算法的个人理解 什么是RSA签名、验签、加密解密1、rsa算法为非对称加密...

jason-寒江雪
2015/12/14
716
0
go语言中椭圆曲线加密算法的使用

椭圆曲线加密算法,使用golang的实现! 最近在看一些关于比特币的东西,里边有个椭圆曲线加密算法,查了下,感觉很不错! 与经典的RSA,DSA等公钥密码体制相比,椭圆密码体制有以下优点: 1.安全性...

IrvinYoung
2016/10/09
144
0
C# 中使用 RSA加解密算法

一、什么是RSA   RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。      在公开...

唐僧他大叔
2017/04/12
0
0
Django开发密码管理表实例【附源码】

  文章及代码比较基础,适合初、中级人员,高手略过      阅读此篇文章你可以:      获取一个Django实现增删改查的案例源码      了解数据加密的使用场景和方法以及如何在Pyt...

SEOwhywhy
12/06
0
0
RSA加解密及签名算法的技术原理及其Go语言实现

  对称加密中,加密和解密使用相同的密钥,因此必须向解密者配送密钥,即密钥配送问题。而非对称加密中,由于加密和解密分别使用公钥和私钥,而公钥是公开的,因此可以规避密钥配送问题。非...

莫名2013
01/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

自定义 Maven 的 repositories

有时,应用中需要一些比较新的依赖,而这些依赖并没有正式发布,还是处于milestone或者是snapshot阶段,并不能从中央仓库或者镜像站上下载到。此时,就需要 自定义Maven的<repositories>。 ...

waylau
5分钟前
0
0
徒手写一个es6代码库

mkdir democd demonpm initnpm install -g babelnpm install -g babel-cli 在项目目录创建两个文件夹 functional-playground 和lib mkdir functional-playgroundmkdir lib...

lilugirl
5分钟前
0
0
linux定位应用问题的一些常用命令,特别针对内存和线程分析的dump命令

1.jps找出进程号,找到对应的进程号后面才好继续操作 2.linux查看进程详细信息 ps -ef | grep 进程ID 3. dump内存信息 Jmap -dump:format=b,file=YYMMddhhmm.dump pid 4.top查看cpu占用信息 ...

noob_chr
6分钟前
0
0
Android TV开发-按键焦点

写在前面 按键焦点过程了解 2.1 dispatchKeyEvent 过程了解 2.2 焦点查找请求过程了解 1.2.1 第一次获取焦点 1.2.3 按键焦点 焦点控制 焦点记忆 应用场景 参考资料 [TOC] 1. 写在前面 工...

冰雪情缘l
6分钟前
0
0
java框架学习日志-3

这章主要是补充一些ioc创建对象的方式,ioc容器在写好<bean></bean>的时候就已经创建对象了。在之前的例子中,一直都是无参的构造方法。下面给出有参的构造方法的对象的创建,没有什么难点重...

白话
8分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部