网络通信技术的迅速发展,使得网络通信中加密存储和加密传输就非常必要。混沌系统对初始值的依赖和极度敏感性,使用混沌序列作为信息的存储和传输中进行加密成为可能。
一、什么是混沌序列
混沌序列是一种伪的随机数。伪随机数看起来是随机,其实是确定序列。示例:(1,4,9,16,...)了解规则后,能写出后面的数字。混沌序列是一种由一个初始值(或称为初始条件)开始的循环算法,初始条件下微小的变化即可导致大范围内不同的结果,这使得信息的保密性大大增强。
混沌序列不仅用于生成随机数,而且还可用于加密和解密。混沌序列的特点是具有较高的混沌性,即序列中的值在空间上分布较为均匀,而且非常不可预测。
二、几种常用的混沌序列算法
1、Logistic映射
Logistic映射是一种可产生的非线性系统,模型表示如下
公式中 0<μ ≤ 4 0 < x < 1; x(n)∈(o,1) 其中μ是分岔参数,当 3.5699456... < μ < 4时,映射进入混沌区域。
golang简单实现
package main
import "fmt"
const (
u = 3.79 // 分岔参数 3.5699456... < μ < 4
)
func main() {
var x float64 = 0.5
for i := 0; i < 100; i++ {
x = u * x * (1 - x)
fmt.Printf("%.3fn", x)
}
}
2、Lorenz方程式
洛伦兹方程是描述空气流体运动的一个简化微分方程组,模型表示如下:
golang代码如下
package main
import (
"fmt"
)
const (
p = 10.0 // 普朗特数
b = 8.0 / 3.0 //正实数
r = 28.0 // 瑞利数 >= 24.74
)
// 主函数
func main() {
x, y, z := 20.12, 20.0, 20.0
dt := 0.01
n := 255
fmt.Printf("%2s %10s %10s %10sn", "k", "x", "y", "z")
fmt.Printf("%2d %10.3f %10.3f %10.3fn", 0, x, y, z)
for k := 1; k <= n; k++ {
x, y, z = Lorenz(x, y, z, dt)
fmt.Printf("%2d %10.3f %10.3f %10.3fn", k, x, y, z)
}
}
func Lorenz(x, y, z, dt float64) (float64, float64, float64) {
x_dt := p * (y - x)
y_dt := r*x - y - x*z
z_dt := x*y - b*z
x += x_dt * dt
y += y_dt * dt
z += z_dt * dt
return x, y, z
}
3、Rossler模型
ω,α,β,γ为系统的参数。我们称 ω为自然频率,是表征系统在没有外界干扰时转动快慢的量.
golang示例如下:
package main
import "fmt"
// 定义常量
const (
h = 0.01
a = 0.2
b = 0.2
c = 5.7
)
// 定义结构体
type Rossler struct {
x, y, z float64
}
// 定义方法
func (r *Rossler) next() {
x_derived := -r.y - r.z
y_derived := r.x + a*r.y
z_derived := b + r.z*(r.x-c)
r.x = r.x + h*x_derived
r.y = r.y + h*y_derived
r.z = r.z + h*z_derived
}
// 主函数
func main() {
r := Rossler{x: 0.1, y: 0, z: 0}
for i := 0; i < 1000; i++ {
fmt.Println(r.x, r.y, r.z)
r.next()
}
}
三、加解密图像
混沌方法的数字图像加密是一种新型的信息安全技术,它利用混沌系统的不可预知性特性实现加密效果。
下面是golang实现混沌方法的数字图像加密实现:
-
将原始图片转换为矩阵,比如图片为512*512像素,则矩阵为512*512,每个元素的值为图片的像素值。
-
建立混沌系统函数,如Logistic,计算混沌序列。
-
将混沌序列作为加密种子,将原始图像矩阵与混沌序列每位相加,并取余数作为加密图像的新像素值。
-
将加密后的矩阵重新转换为图片,即完成混沌方法的数字图像加密实现。
package main
import (
"encoding/json"
"github.com/Comdex/imgo"
"image"
"image/color"
"image/png"
"log"
"os"
)
func main() {
key := [6]float64{0.343, 0.432, 0.63, 3.769, 3.82, 3.85}
saveGrayFile("img/512.png", "img/gray512.png")
encrypt("img/gray512.png", "img/encrypt512.png", key)
decrypt("img/encrypt512.png", "img/decrypt512.png", key)
key1 := [6]float64{0.34, 0.432, 0.63, 3.769, 3.82, 3.85}
decrypt("img/encrypt512.png", "img/fail_decrypt512.png", key1)
}
// 生成灰度
func saveGrayFile(origin, outfile string) {
open, err2 := os.Open(origin)
defer open.Close()
if err2 != nil {
log.Fatal(err2)
}
img, _, err2 := image.Decode(open)
if err2 != nil {
log.Fatal(err2)
}
bounds := img.Bounds()
dx := bounds.Dx()
dy := bounds.Dy()
newRgba := image.NewRGBA(bounds)
for x := 0; x < dx; x++ {
for y := 0; y < dy; y++ {
colorRgb := img.At(x, y)
_, g, _, a := colorRgb.RGBA()
newG := uint8(g >> 8)
newA := uint8(a >> 8)
// 将每个点的设置为灰度值
newRgba.SetRGBA(x, y, color.RGBA{R: newG, G: newG, B: newG, A: newA})
}
}
imgfile, err := os.Create(outfile)
if nil != err {
log.Fatal(err)
}
err = png.Encode(imgfile, newRgba)
if nil != err {
log.Fatal(err)
}
}
// 深度拷贝,避免切片指针引用
func zero(matrix [][][]uint8) [][][]uint8 {
tmp := make([][][]uint8, len(matrix))
marshal, err := json.Marshal(matrix)
if err != nil {
log.Fatalf("zero %s", err.Error())
}
err = json.Unmarshal(marshal, &tmp)
if err != nil {
log.Fatalf("zero %s", err.Error())
}
return tmp
}
// 加密
func encrypt(origin, outfile string, key [6]float64) error {
// 混沌系统初始条件
x1 := key[0]
x2 := key[1]
x3 := key[2]
// 分岔参数
u1 := key[3]
u2 := key[4]
u3 := key[5]
matrix := imgo.MustRead(origin)
tmp := zero(matrix)
for i, i1 := range matrix {
for j, rgb := range i1 {
x1 = u1 * x1 * (1 - x1)
x2 = u2 * x2 * (1 - x2)
x3 = u3 * x3 * (1 - x3)
r1 := int(x1 * 255)
r2 := int(x2 * 255)
r3 := int(x3 * 255)
// 红色
tmp[i][j][0] = uint8(((int)(rgb[0]) + ((r1 + r2) ^ r3)) % 256)
// 绿色
tmp[i][j][1] = uint8(((int)(rgb[1]) + ((r1 + r2) ^ r3)) % 256)
// 蓝色
tmp[i][j][2] = uint8(((int)(rgb[2]) + ((r1 + r2) ^ r3)) % 256)
}
x1 = key[0]
x2 = key[1]
x3 = key[3]
}
err := imgo.SaveAsPNG(outfile, tmp)
if err != nil {
return err
}
return nil
}
// 解密
func decrypt(origin, outfile string, key [6]float64) error {
// 混沌系统初始条件
x1 := key[0]
x2 := key[1]
x3 := key[2]
// 分岔参数
u1 := key[3]
u2 := key[4]
u3 := key[5]
matrix := imgo.MustRead(origin)
tmp := zero(matrix)
for i, i1 := range matrix {
for j, rgb := range i1 {
x1 = u1 * x1 * (1 - x1)
x2 = u2 * x2 * (1 - x2)
x3 = u3 * x3 * (1 - x3)
r1 := int(x1 * 255)
r2 := int(x2 * 255)
r3 := int(x3 * 255)
// 红色
tmp[i][j][0] = uint8(((int)(rgb[0]) - ((r1 + r2) ^ r3)) % 256)
// 绿色
tmp[i][j][1] = uint8(((int)(rgb[1]) - ((r1 + r2) ^ r3)) % 256)
// 蓝色
tmp[i][j][2] = uint8(((int)(rgb[2]) - ((r1 + r2) ^ r3)) % 256)
}
x1 = key[0]
x2 = key[1]
x3 = key[3]
}
err := imgo.
SaveAsPNG(outfile, tmp)
if err != nil {
return err
}
return nil
}
上面示例代码效果如下图:
秘钥仅仅做微小的修改,就不能正确解密图像了
混沌序列还能应用多种加解密场景,比如:网络传输、数据库指纹等。
原文始发于微信公众号(数据安全治理技术):混沌序列介绍及加密中应用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论