golang基于NaCL EC25519的简单加密管道工具插件库naclpipe的使用

Golang基于NaCL EC25519的简单加密管道工具插件库naclpipe的使用

简介

naclpipe是一个实验性的Go语言包,提供了基于NaCL加密后端的io.Reader/io.Writer接口实现。NaCL(发音为"Salt")是一个现代加密库,支持EC25519曲线加密。

主要特性

  • 使用NaCL ECC 25519实现box/secretbox加密,采用Salsa20算法和Poly1305 MAC
  • 支持Argon2和Scrypt密钥派生函数
  • 使用SHA-3生成NONCE
  • 提供简单的io.Reader/Writer接口

使用示例

基本读取示例

import "github.com/unix4fun/naclpipe"

// 定义读取块大小,可以是任意值
block := make([]byte, 8192)

// 从标准输入初始化读取器
cryptoReader, err := naclpipe.NewReader(os.Stdin, "mysuperduperpassword", naclpipe.DerivateArgon2id)
if err != nil {
    log.Fatalf("naclpipe初始化错误")
}

// 读取并解密数据块
_, err := cryptoReader.Read(block)

完整加密解密示例

package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	
	"github.com/unix4fun/naclpipe"
)

func main() {
	// 原始数据
	plaintext := []byte("这是一条需要加密的测试消息")
	
	// 创建缓冲区
	var cipherBuf bytes.Buffer
	
	// 初始化加密写入器
	password := "securepassword123"
	cryptoWriter, err := naclpipe.NewWriter(&cipherBuf, password, naclpipe.DerivateArgon2id)
	if err != nil {
		log.Fatal(err)
	}
	
	// 写入并加密数据
	if _, err := cryptoWriter.Write(plaintext); err != nil {
		log.Fatal(err)
	}
	
	// 关闭写入器以确保所有数据都已刷新
	if err := cryptoWriter.Close(); err != nil {
		log.Fatal(err)
	}
	
	// 打印加密后的数据
	fmt.Printf("加密后的数据: %x\n", cipherBuf.Bytes())
	
	// 现在解密数据
	var plainBuf bytes.Buffer
	
	// 初始化解密读取器
	cryptoReader, err := naclpipe.NewReader(&cipherBuf, password, naclpipe.DerivateArgon2id)
	if err != nil {
		log.Fatal(err)
	}
	
	// 读取并解密数据
	if _, err := io.Copy(&plainBuf, cryptoReader); err != nil {
		log.Fatal(err)
	}
	
	// 打印解密后的数据
	fmt.Printf("解密后的数据: %s\n", plainBuf.String())
}

密钥派生函数

naclpipe支持两种密钥派生函数:

  1. naclpipe.DerivateArgon2id - 使用Argon2id算法
  2. naclpipe.DerivateScrypt - 使用Scrypt算法

建议使用Argon2id作为默认选择,因为它提供了更好的安全特性。

变更日志

  • 2018-11-17

    • 移除了旧的向后兼容代码
    • 发布0.2.0版本
  • 2018-06-24

    • 添加了argon2id密钥派生函数
    • 升级了密钥派生函数和参数
    • 添加了godoc文档
  • 2018-04-01

    • 分离了np命令和naclpipe包
    • 添加了可重用的io.Reader/Writer接口
    • 开始使用语义化版本控制,初始版本为0.1.0
  • 2018-03-24

    • 修复了Tom Eklof报告的空scrypt salt问题
    • 改进了管道输入处理
    • 结构调整,将CSPRNG生成的salt添加到数据块前

注意事项

  1. 确保使用强密码
  2. 对于生产环境,建议使用更大的密钥派生参数(虽然会增加计算时间)
  3. 加密数据不包含元数据,需要自行管理密钥和加密参数

这个库提供了一个简单的方式来加密/解密数据流,适合需要快速实现加密通信或加密存储的场景。


更多关于golang基于NaCL EC25519的简单加密管道工具插件库naclpipe的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于NaCL EC25519的简单加密管道工具插件库naclpipe的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用NaCL EC25519的Go加密管道工具:naclpipe

NaCL (Networking and Cryptography Library) 是一个现代加密库,提供了简单易用的加密原语。在Go中,我们可以使用golang.org/x/crypto/nacl包来实现基于EC25519的加密管道。下面我将介绍如何创建一个简单的加密管道工具库。

基本概念

NaCL的EC25519提供了:

  • 密钥对生成
  • 非对称加密/解密
  • 数字签名
  • 密钥交换

实现代码

package naclpipe

import (
	"crypto/rand"
	"errors"
	"io"
	"golang.org/x/crypto/nacl/box"
	"golang.org/x/crypto/nacl/secretbox"
)

// 生成新的密钥对
func GenerateKeyPair() (publicKey, privateKey *[32]byte, err error) {
	publicKey, privateKey, err = box.GenerateKey(rand.Reader)
	return
}

// 加密管道结构体
type EncryptedPipe struct {
	sharedKey *[32]byte
}

// 创建新的加密管道
func NewEncryptedPipe(ourPrivateKey, theirPublicKey *[32]byte) *EncryptedPipe {
	var sharedKey [32]byte
	box.Precompute(&sharedKey, theirPublicKey, ourPrivateKey)
	return &EncryptedPipe{sharedKey: &sharedKey}
}

// 加密数据
func (p *EncryptedPipe) Encrypt(plaintext []byte) ([]byte, error) {
	var nonce [24]byte
	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
		return nil, err
	}

	encrypted := secretbox.Seal(nonce[:], plaintext, &nonce, p.sharedKey)
	return encrypted, nil
}

// 解密数据
func (p *EncryptedPipe) Decrypt(ciphertext []byte) ([]byte, error) {
	if len(ciphertext) < 24 {
		return nil, errors.New("ciphertext too short")
	}

	var nonce [24]byte
	copy(nonce[:], ciphertext[:24])
	decrypted, ok := secretbox.Open(nil, ciphertext[24:], &nonce, p.sharedKey)
	if !ok {
		return nil, errors.New("decryption error")
	}

	return decrypted, nil
}

// 创建加密的读写管道
func NewEncryptedReadWriter(rw io.ReadWriter, pipe *EncryptedPipe) *EncryptedReadWriter {
	return &EncryptedReadWriter{
		rw:   rw,
		pipe: pipe,
	}
}

type EncryptedReadWriter struct {
	rw   io.ReadWriter
	pipe *EncryptedPipe
}

func (erw *EncryptedReadWriter) Read(p []byte) (n int, err error) {
	// 先读取加密数据
	ciphertext := make([]byte, 1024) // 适当大小
	n, err = erw.rw.Read(ciphertext)
	if err != nil {
		return 0, err
	}

	// 解密数据
	plaintext, err := erw.pipe.Decrypt(ciphertext[:n])
	if err != nil {
		return 0, err
	}

	copy(p, plaintext)
	return len(plaintext), nil
}

func (erw *EncryptedReadWriter) Write(p []byte) (n int, err error) {
	// 加密数据
	ciphertext, err := erw.pipe.Encrypt(p)
	if err != nil {
		return 0, err
	}

	// 写入加密数据
	return erw.rw.Write(ciphertext)
}

使用示例

package main

import (
	"fmt"
	"naclpipe" // 假设上面的代码在naclpipe包中
)

func main() {
	// 生成双方的密钥对
	alicePublic, alicePrivate, _ := naclpipe.GenerateKeyPair()
	bobPublic, bobPrivate, _ := naclpipe.GenerateKeyPair()

	// 创建加密管道
	alicePipe := naclpipe.NewEncryptedPipe(alicePrivate, bobPublic)
	bobPipe := naclpipe.NewEncryptedPipe(bobPrivate, alicePublic)

	// 测试加密解密
	message := []byte("Hello, secure world!")

	// Alice加密消息
	encrypted, _ := alicePipe.Encrypt(message)
	fmt.Printf("Encrypted: %x\n", encrypted)

	// Bob解密消息
	decrypted, _ := bobPipe.Decrypt(encrypted)
	fmt.Printf("Decrypted: %s\n", decrypted)

	// 也可以创建加密的读写器用于网络通信等场景
	// pr, pw := io.Pipe()
	// aliceRW := naclpipe.NewEncryptedReadWriter(pw, alicePipe)
	// bobRW := naclpipe.NewEncryptedReadWriter(pr, bobPipe)
	// 然后就可以像普通io.ReadWriter一样使用了
}

注意事项

  1. Nonce管理:上面的实现每次加密都生成新的nonce,确保安全性。在实际应用中,必须确保nonce不会重复使用。

  2. 密钥安全:私钥必须严格保密,公钥可以安全地共享。

  3. 消息认证:NaCL的secretbox已经提供了消息认证,确保数据完整性和真实性。

  4. 性能考虑:对于大量数据,可以考虑使用流式加密而非每次加密整个消息。

这个简单的库提供了基于NaCL EC25519的基本加密管道功能,可以用于安全通信、文件加密等场景。根据具体需求,可以进一步扩展功能。

回到顶部