Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >加密解密 CTR IGE DH等

加密解密 CTR IGE DH等

作者头像
solate
发布于 2019-07-22 08:28:32
发布于 2019-07-22 08:28:32
1.2K00
代码可运行
举报
文章被收录于专栏:solate 杂货铺solate 杂货铺
运行总次数:0
代码可运行

加密解密

块加密

AES

IGE 模式

ige github例子

分组模式

CTR 模式

CTR 全称为计数器模式(Counter mode),该模式由 Diffe 和 Hellman 设计。一种分组密码的模式

DH 秘钥交换算法

一种密钥交换协议,注意该算法只能用于密钥的交换,而不能进行消息的加密和解密。双方确定要用的密钥后,要使用其他对称密钥操作加密算法实际加密和解密消息。它可以让双方在不泄漏密钥的情况下协商出一个密钥来, 常用于保证对称加密的秘钥的安全, TLS就是这样做的。

  • DH:ECDH是DH的加强版
  • ECDH: DH算法的加强版, 常用的是NIST系列,但是后面curve25519
  • curve25519: 实质上也是一种ECDH,但是其实现更为优秀,表现的更为安全,可能是下一代秘钥交换算法的标准。
DH go 的实现

引用git: dh go实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Use of this source code is governed by a license
// that can be found in the LICENSE file.

// Package dh implements the Diffie-Hellman key exchange over
// multiplicative groups of integers modulo a prime.
// This also defines some commen groups described in RFC 3526.
package dh

import (
	cryptorand "crypto/rand"
	"errors"
	"io"
	"math/big"
)

var zero *big.Int = big.NewInt(0)
var one *big.Int = big.NewInt(1)
var two *big.Int = big.NewInt(2)

// IsSafePrime returns true, if the prime of the group is
// a so called safe-prime. For a group with a safe-prime prime
// number the Decisional-Diffie-Hellman-Problem (DDH) is a
// 'hard' problem. The n argument is the number of iterations
// for the probabilistic prime test.
// It's recommend to use DDH-safe groups for DH-exchanges.
func IsSafePrimeGroup(g *Group, n int) bool {
	q := new(big.Int).Sub(g.P, one)
	q = q.Div(q, two)
	return q.ProbablyPrime(n)
}

// PublicKey is the type of DH public keys.
type PublicKey *big.Int

// PrivateKey is the type of DH private keys.
type PrivateKey *big.Int

// Group represents a mathematical group defined
// by a large prime and a generator.
type Group struct {
	P *big.Int // The prime
	G *big.Int // The generator
}

// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func (g *Group) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) {
	if g.P == nil {
		panic("crypto/dh: group prime is nil")
	}
	if g.G == nil {
		panic("crypto/dh: group generator is nil")
	}
	if rand == nil {
		rand = cryptorand.Reader
	}

	// Ensure, that p.G ^ privateKey > than g.P
	// (only modulo calculations are safe)
	// The minimal (and common) value for p.G is 2
	// So 2 ^ (1 + 'bitsize of p.G') > than g.P
	min := big.NewInt(int64(g.P.BitLen() + 1)) //生成一个不小于p的大数
	bytes := make([]byte, (g.P.BitLen()+7)/8)  //bit/8 = byte, +7 是为了补空,放置少除了,然后长度不够

	for private == nil {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			private = nil
			return
		}
		// Clear bits in the first byte to increase
		// the probability that the candidate is < g.P.
		bytes[0] = 0
		if private == nil {
			private = new(big.Int)
		}
		(*private).SetBytes(bytes)   //将读到的数据设置进private中
		if (*private).Cmp(min) < 0 { //private 小于 一个不小于p的数。 如x < y返回-1;如x > y返回+1;否则返回0。
			private = nil
		}
	}

	public = new(big.Int).Exp(g.G, private, g.P) //x**y mod |m| =  A = g**a mod p
	return
}

// PublicKey returns the public key corresponding to the given private one.
func (g *Group) PublicKey(private PrivateKey) (public PublicKey) {
	public = new(big.Int).Exp(g.G, private, g.P)
	return
}

//private returns a non-nil error if the given public key is
// not a possible element of the group. This means, that the
// public key is < 0 or > g.P.
func (g *Group) Check(peersPublic PublicKey) (err error) {
	if !((*peersPublic).Cmp(zero) >= 0 && (*peersPublic).Cmp(g.P) == -1) {
		err = errors.New("peer's public is not a possible group element")
	}
	return
}

// ComputeSecret returns the secret computed from
// the own private and the peer's public key.
func (g *Group) ComputeSecret(private PrivateKey, peersPublic PublicKey) (secret *big.Int) {
	secret = new(big.Int).Exp(peersPublic, private, g.P)
	return
}

ECDH

全称是Elliptic Curve Diffie-Hellman, 是DH算法的加强版, 基于椭圆曲线难题加密, 现在是主流的密钥交换算法。

ECC是建立在基于椭圆曲线的离散对数的难度, 大概过程如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
给定椭圆曲线上的一个点P,一个整数k,求解Q=kP很容易;给定一个点PQ,知道Q=kP,求整数k确是一个难题。ECDH即建立在此数学难题之上
ECDH 和 curve25519 go的实现

引用: 密码学简介与Golang的加密库Crypto的使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main
import (
	"crypto"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"io"
	"math/big"
	"golang.org/x/crypto/curve25519"
)
// ECDH 秘钥交换算法的主接口
type ECDH interface {
	GenerateKey(io.Reader) (crypto.PrivateKey, crypto.PublicKey, error)
	Marshal(crypto.PublicKey) []byte
	Unmarshal([]byte) (crypto.PublicKey, bool)
	GenerateSharedSecret(crypto.PrivateKey, crypto.PublicKey) ([]byte, error)
}
type ellipticECDH struct {
	ECDH
	curve elliptic.Curve
}
type ellipticPublicKey struct {
	elliptic.Curve
	X, Y *big.Int
}
type ellipticPrivateKey struct {
	D []byte
}
// NewEllipticECDH 指定一种椭圆曲线算法用于创建一个ECDH的实例
// 关于椭圆曲线算法标准库里面实现了4种: 见crypto/elliptic
func NewEllipticECDH(curve elliptic.Curve) ECDH {
	return &ellipticECDH{
		curve: curve,
	}
}
// GenerateKey 基于标准库的NIST椭圆曲线算法生成秘钥对
func (e *ellipticECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) {
	var d []byte
	var x, y *big.Int
	var priv *ellipticPrivateKey
	var pub *ellipticPublicKey
	var err error
	d, x, y, err = elliptic.GenerateKey(e.curve, rand)
	if err != nil {
		return nil, nil, err
	}
	priv = &ellipticPrivateKey{
		D: d,
	}
	pub = &ellipticPublicKey{
		Curve: e.curve,
		X:     x,
		Y:     y,
	}
	return priv, pub, nil
}
// Marshal用于公钥的序列化
func (e *ellipticECDH) Marshal(p crypto.PublicKey) []byte {
	pub := p.(*ellipticPublicKey)
	return elliptic.Marshal(e.curve, pub.X, pub.Y)
}
// Unmarshal用于公钥的反序列化
func (e *ellipticECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) {
	var key *ellipticPublicKey
	var x, y *big.Int
	x, y = elliptic.Unmarshal(e.curve, data)
	if x == nil || y == nil {
		return key, false
	}
	key = &ellipticPublicKey{
		Curve: e.curve,
		X:     x,
		Y:     y,
	}
	return key, true
}
// GenerateSharedSecret 通过自己的私钥和对方的公钥协商一个共享密码
func (e *ellipticECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) {
	priv := privKey.(*ellipticPrivateKey)
	pub := pubKey.(*ellipticPublicKey)
	x, _ := e.curve.ScalarMult(pub.X, pub.Y, priv.D)
	return x.Bytes(), nil
}
// NewCurve25519ECDH 使用密码学家Daniel J. Bernstein的椭圆曲线算法:Curve25519来创建ECDH实例
// 因为Curve25519独立于NIST之外, 没在标准库实现, 需要单独为期实现一套接口来支持ECDH
func NewCurve25519ECDH() ECDH {
	return &curve25519ECDH{}
}
type curve25519ECDH struct {
	ECDH
}
// GenerateKey 基于curve25519椭圆曲线算法生成秘钥对
func (e *curve25519ECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) {
	var pub, priv [32]byte
	var err error
	_, err = io.ReadFull(rand, priv[:])
	if err != nil {
		return nil, nil, err
	}
	priv[0] &= 248
	priv[31] &= 127
	priv[31] |= 64
	curve25519.ScalarBaseMult(&pub, &priv)
	return &priv, &pub, nil
}
// 实现公钥的序列化
func (e *curve25519ECDH) Marshal(p crypto.PublicKey) []byte {
	pub := p.(*[32]byte)
	return pub[:]
}
// 实现公钥的反序列化
func (e *curve25519ECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) {
	var pub [32]byte
	if len(data) != 32 {
		return nil, false
	}
	copy(pub[:], data)
	return &pub, true
}
// 实现秘钥协商接口
func (e *curve25519ECDH) GenerateSharedSecret(privKey crypto.PrivateKey, pubKey crypto.PublicKey) ([]byte, error) {
	var priv, pub, secret *[32]byte
	priv = privKey.(*[32]byte)
	pub = pubKey.(*[32]byte)
	secret = new([32]byte)
	curve25519.ScalarMult(secret, priv, pub)
	return secret[:], nil
}
func test(e ECDH) {
	var privKey1, privKey2 crypto.PrivateKey
	var pubKey1, pubKey2 crypto.PublicKey
	var pubKey1Buf, pubKey2Buf []byte
	var err error
	var ok bool
	var secret1, secret2 []byte
	// 准备2对秘钥对,A: privKey1,pubKey1 B:privKey2,pubKey2
	privKey1, pubKey1, err = e.GenerateKey(rand.Reader)
	if err != nil {
		fmt.Println(err)
	}
	privKey2, pubKey2, err = e.GenerateKey(rand.Reader)
	if err != nil {
		fmt.Println(err)
	}
	pubKey1Buf = e.Marshal(pubKey1)
	pubKey2Buf = e.Marshal(pubKey2)
	pubKey1, ok = e.Unmarshal(pubKey1Buf)
	if !ok {
		fmt.Println("Unmarshal does not work")
	}
	pubKey2, ok = e.Unmarshal(pubKey2Buf)
	if !ok {
		fmt.Println("Unmarshal does not work")
	}
	// A 通过B给的公钥协商共享密码
	secret1, err = e.GenerateSharedSecret(privKey1, pubKey2)
	if err != nil {
		fmt.Println(err)
	}
	// B 通过A给的公钥协商共享密码
	secret2, err = e.GenerateSharedSecret(privKey2, pubKey1)
	if err != nil {
		fmt.Println(err)
	}
	// A B在没暴露直接的私钥的情况下, 协商出了一个共享密码
	fmt.Printf("The secret1 shared keys: %x\n", secret1)
	fmt.Printf("The secret2 shared keys: %x\n", secret2)
}
func main() {
	e1 := NewEllipticECDH(elliptic.P521())
	e2 := NewCurve25519ECDH()
	test(e1)
	test(e2)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
保姆级参考基因组及其注释下载教程(图文详解)
自从 1990 启动的家喻户晓的人类基因组计划开始,全世界的科学家竭尽全力破译了第一个完整的人类基因组,从那时开始人类拿到了一本只有 ATCG 四个碱基书写的天书。后续人们逐步完善了基因组序列信息,并写在 Fasta 格式的文本文件“天书”中,这本天书就叫做参考基因组。
生信菜鸟团
2021/07/05
12.6K0
保姆级参考基因组及其注释下载教程(图文详解)
(15)基因组各种版本对应关系-生信菜鸟团博客2周年精选文章集
这是我的成名作: 首先是NCBI对应UCSC,对应ENSEMBL数据库: GRCh36 (hg18): ENSEMBL release_52. GRCh37 (hg19): ENSEMBL release_59/61/64/68/69/75. GRCh38 (hg38): ENSEMBL release_76/77/78/80/81/82. 可以看到ENSEMBL的版本特别复杂!!!很容易搞混! 但是UCSC的版本就简单了,就hg18,19,38, 常用的是hg19,但是我推荐大家都转为hg38 看起来N
生信技能树
2018/03/08
1.9K0
不可不知的基因组版本对应关系
不同版本对应关系 hg19,GRCH37和Ensembl75是三种国际生物信息学数据库资源收集存储单位,即NCBI,UCSC和ENSEMBL各自发布的基因组信息。 hg系列,hg18/19/38来自UCSC,也是目前使用频率最高的基因组。从出道至今我就只看过hg19了,但是建议大家都转为hg38,因为它是目前的最新版本。 基因组各种版本对应关系综合来看如下所示: GRCh36 (hg18): ENSEMBL release_52. GRCh37 (hg19): ENSEMBL release_59/61/6
生信技能树
2018/03/08
3.8K0
一文读懂参考基因组和基因组注释+最全下载方法
自从 1990 启动的家喻户晓的人类基因组计划开始,全世界的科学家竭尽全力破译了第一个完整的人类基因组,从那时开始人类拿到了一本只有 ATCG 四个碱基书写的天书。后续人们逐步完善了基因组序列信息,并写在 Fasta 格式的文本文件“天书”中,这本天书就叫做参考基因组。
白墨石
2021/06/10
3.3K0
一文读懂参考基因组和基因组注释+最全下载方法
熟悉数据库的下载
生物数据的处理本质上有两条路线:其中一条是序列本身具有结构特征,那么就可以通过软件算法来实现,比如预测基因,非编码 RNA,重复序列的分析等;另一条路线是序列本身没有结构特征,只能通过与已有序列进行比对,根据已知信息来推测未知信息,比如基因功能注释,16SrRNA 物种鉴定等,常见的一个例子就是得到一条序列,需要判断序列来自于哪个物种,就只能与数据库进行比对。
生信喵实验柴
2021/12/21
1.7K0
熟悉数据库的下载
转录组参考基因-5
首先转录组数据分析流程如下,之前的课程中已经介绍过文件夹的建立和原始数据的过滤,接下来要进行基因比对——将测序数据与基因文件进行匹配。
生信菜鸟团
2024/07/10
1350
转录组参考基因-5
转录组——上游分析
FastQC主页:http://www.bioinformatics.babraham.ac.uk/projects/fastqc/
青柠味
2025/06/12
1030
转录组——上游分析
转录组 - 比对
生信技能树学习笔记 参考基因组准备 常用参考基因组 Ensembl asia.ensembl.org/index.html NCBI UCSC ## 进入参考基因组目录 mkdir -p $HOME/database/GRCh38.105 cd $HOME/database/GRCh38.105 ## 下载基因组 ## 一般选择primary assembly,没有的话可以选择toplevel nohup wget -c https://ftp.ensembl.org/pub/release-105/fa
用户10328045
2023/03/02
1.4K0
详解参考基因组的下载方式
在数据分析中,经常需要下载物种的参考基因组序列。通常情况下,可以考虑以下3个数据库
生信修炼手册
2020/05/08
3.7K0
详解参考基因组的下载方式
转录组数据分析-比对
Ensembl:www.ensembl.org #用得最多数据库完善有基因对应的ID
用户10412487
2023/05/09
6700
优秀学员笔记:转录组课堂笔记Day1~2
双端测序:一般一个样本对应两个fq文件,gz是压缩后缀,如SRR1039510对应
生信技能树
2025/04/30
1590
优秀学员笔记:转录组课堂笔记Day1~2
转录组测序分析专题——比对/定量
NCBI:https://www.ncbi.nlm.nih.gov/projects/genome/gu ide/human/index.shtml
yurric
2023/10/26
9950
安装VEP及其注释数据库
为了其它相关软件的顺利运行,我们根据教程来设置默认的安装目录及变量环境:Ensembl's VEP , If you don't have VEP installed, then follow this gist.
生信技能树
2018/07/27
4.6K0
RNA-seq(4):下载参考基因组及基因注释
那下载哪个基因组呢?先了解一下: https://bitesizebio.com/38335/get-to-know-your-reference-genome-grch37-vs-grch38/
Y大宽
2018/09/10
5.3K0
RNA-seq(4):下载参考基因组及基因注释
STAR:转录组数据比对工具简介
STAR是一款RNA_seq数据专用的比对软件,比对速度非常快,最大的优势是灵敏度高,GATK推荐采用STAR比对,然后进行下游的SNP分析。软件的源代码保存在github上,地址如下
生信修炼手册
2020/05/08
6K0
转录组—上游分析_如何拿到count矩阵
本文档记录GSE149638数据集中下载SRR11652578和SRR11652615原始数据
sheldor没耳朵
2024/08/12
5541
转录组—上游分析_如何拿到count矩阵
VEP — 高效的变异注释工具
Ensembl Variant Effect Predictor (VEP) 是由欧洲生物信息研究所(European Bioinformatics Institute, EMBL-EBI)开发的一个高效的基因变异注释工具。VEP是一个强大的工具,其具有以下特性:
生信菜鸟团
2024/04/11
2.2K0
VEP — 高效的变异注释工具
详解GFF转换为GTF文件
存储基因和转录本的结构信息,gtf和gff3两种格式都可以。在实际分析时,会需要转换两种格式。比如,NCBI 只提供了GFF格式的下载文件,我们需要转换成GTF文件之后再使用。
生信修炼手册
2020/05/08
4.9K0
跟小新老师学转录组的第三天
NCBI:https://www.ncbi.nlm.nih.gov/projects/genome/guide/human/index.shtml
贝诺酯
2023/04/03
3350
全基因组 - 人类基因组变异分析(PacBio) (3)-- pbmm2
长读段比对算法与一代/二代测序数据的比对算法有很大的不同,因为长读段通常更长、包含更多错误和变异,并且需要更复杂的比对策略。
三代测序说
2023/10/26
1.4K1
全基因组 - 人类基因组变异分析(PacBio) (3)-- pbmm2
相关推荐
保姆级参考基因组及其注释下载教程(图文详解)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验