AES过程
来源:互联网 发布:练六级英语听力的软件 编辑:程序博客网 时间:2024/05/29 09:29
- 分块密码, 因此要求被加密对象长度为块长度的倍数
- 秘钥长度必须是16或者24或者32 分别对应AES-128, AES-192, AES-256
- 需要以某种形式将明文的长度编码
- 加密算法有cipher.NewCBCEncrypter, cipher.NewCFBEncrypter, 但是他们返回的对象分别是Block和Stream。 未比较块和流的优点缺点。
只要理解了这个过程代码非常好调。
package mainimport ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/binary" "fmt" "io" "unsafe")// PCKS paddingfunc padKey(key []byte) []byte { var targetKeySize = 16 if len(key) <= 16 { targetKeySize = 16 } else if len(key) <= 24 { targetKeySize = 24 } else { targetKeySize = 32 } if r := targetKeySize - len(key); r > 0 { nkey := make([]byte, targetKeySize) copy(nkey, key) copy(nkey[len(key):], bytes.Repeat([]byte{byte(r)}, r)) key = nkey } return key[:targetKeySize]}func encrypt(source []byte, keyStr string) ([]byte, error) { srcLength := len(source) var usize uint64 headSize := int(unsafe.Sizeof(usize)) head := make([]byte, headSize, headSize+len(source)) source = append(head, source...) len0 := len(source) if r := len0 % aes.BlockSize; r > 0 { len0 += aes.BlockSize - r padding := make([]byte, aes.BlockSize-r) if _, err := io.ReadFull(rand.Reader, padding); err != nil { return nil, err } source = append(source, padding...) } buffer := make([]byte, len0+aes.BlockSize) iv := buffer[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return nil, err } usize = uint64(srcLength) binary.BigEndian.PutUint64(source, usize) block, ec := aes.NewCipher(padKey([]byte(keyStr))) if ec != nil { return nil, ec } mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(buffer[aes.BlockSize:], source) return buffer, nil}func decrypt(encbuffer []byte, keyStr string) ([]byte, error) { iv := encbuffer[:aes.BlockSize] out := encbuffer[aes.BlockSize:] block, ec := aes.NewCipher(padKey([]byte(keyStr))) if ec != nil { return nil, ec } mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(out, out) usize := binary.BigEndian.Uint64(out) var headSize = int(unsafe.Sizeof(usize)) return out[headSize : headSize+int(usize)], nil}func encTest(src, key string) { ebuff, err := encrypt([]byte(src), key) if err != nil { panic(err) } dbuff, err := decrypt(ebuff, key) if err != nil { panic(err) } fmt.Printf("<%v> : len = %v (encrypted length=%v)\n", string(dbuff), len(dbuff), len(ebuff), ) fmt.Printf("<%v>\n", ebuff)}func main() { src := []byte("hasta victoria siempre") encrypted, err := encrypt(src, "klo") if err != nil { panic(err) } fmt.Printf("%v\n", encrypted) fmt.Printf("len for encrypted: %v\n", len(encrypted)) decrypted, err := decrypt(encrypted, "klo") if err != nil { panic(err) } fmt.Printf("decrypted len is: %v\n", len(decrypted)) fmt.Printf("decrypted: %v\n", string(decrypted)) encTest("", "a") encTest("", "ss") encTest("a", "") encTest("a", "aa")}
reference link:
https://stackoverflow.com/questions/24072026/golang-aes-ecb-encryption
https://stackoverflow.com/questions/18817336/golang-encrypting-a-string-with-aes-and-base64
https://www.ctolib.com/topics-3631.html
http://www.cnblogs.com/lianghui66/archive/2013/03/07/2948494.html
http://gunn.me/2015/07/213/
http://www.cnblogs.com/lavin/p/5373188.html
https://segmentfault.com/a/1190000004151272
https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption/20946#20946
http://www.cnblogs.com/happyhippy/archive/2006/12/23/601357.html
https://baike.baidu.com/item/Diffie-Hellman
最后附上nodejs(其他工具的实现)
const crypto = require('crypto');const assert = require('assert');//bufffunction padKey(buffStr){ let buffKey = Buffer.from(buffStr); let targetLen = 16; if(buffKey.length<=16){ targetLen = 16; } else if(buffKey.length<=24){ targetLen = 24; } else { targetLen = 32; } let r = targetLen - buffKey.length; if (r>0) { let padding = Buffer.alloc(r, r); buffKey = Buffer.concat([buffKey, padding]); } return buffKey.slice(0, targetLen);}function randInt8(){ return Math.floor(Math.random() * 256);}/// a buffer of length equals block-sizefunction randIv() { let rv = Buffer.alloc(16, 0); rv.forEach((c,i)=>{ rv[i] = randInt8(); }); return rv;}function makeCipherName(k){ let cipherName = 'aes-128-cbc'; //cipher block chain switch(k.length){ case 16: cipherName = 'aes-128-cbc'; break; case 24: cipherName = 'aes-192-cbc'; break; case 32: cipherName = 'aes-256-cbc'; break; default: throw new Error(`unknown key length ${k.length}`); } return cipherName;}function makeCipher(k, iv){ let algoName = makeCipherName(k); return crypto.createCipheriv(algoName, k, iv);}function makeDecipher(k, iv){ let algoName = makeCipherName(k); return crypto.createDecipheriv(algoName, k, iv);}// using uint64 as the headfunction encrypt(source, keyStr){ let srcBuff = Buffer.from(source); let headBuff = Buffer.alloc(8, 0) headBuff.writeUInt32BE(srcBuff.length, 4); srcBuff = Buffer.concat([headBuff, srcBuff]); let r = srcBuff.length % 16; if(r>0){ srcPadding = Buffer.alloc(16 - r, 0); srcPadding.forEach((c,i)=>{srcPadding[i] = randInt8()}); } let startiv = randIv(); let cipher = makeCipher(padKey(keyStr), startiv); let buffs = [startiv]; buffs.push(cipher.update(srcBuff)); buffs.push(cipher.final()); return Buffer.concat(buffs);}function decrypt(chunk, keyStr){ if(Buffer.isBuffer(chunk)){ //nada } else { chunk = Buffer.from(chunk, 'hex'); } //console.log("tot length is(encoded): %s", chunk.length); let iv = chunk.slice(0, 16) chunk = chunk.slice(16); let cipher = makeDecipher(padKey(keyStr), iv); let decoded = []; decoded.push(cipher.update(chunk)); decoded.push(cipher.final()); decoded = Buffer.concat(decoded); //console.log("decoded length is %s", decoded.length); let len = decoded.readUInt32BE(4); return decoded.slice(8, 8+len);}if(process.argv.length<4){ console.error("not enough parameters"); process.exit(-1);}//console.log(encrypt('hasta victoria siempre', 'kl1'));let encrypted = encrypt(process.argv[2], process.argv[3]);console.log(encrypted.toString('hex'));console.log(encrypted.toString('utf8'));let decrypted = decrypt(encrypted, process.argv[3]);console.log(decrypted.toString());
阅读全文
0 0
- AES过程
- aes 数据流编解码过程
- AES
- AES
- AES
- AES
- aes
- aes
- AES
- AES
- AES
- AES
- PHP开发过程中AES加密解密问题 js前端AES加密,PHP解密
- mysql通过存储过程实现aes加解密
- 用SQL语言创建AES加解密的存储过程
- RSA/AES在通信交互过程中使用
- AES加解密在php接口请求过程中的应用
- AES AES-CBC-128
- ubuntu安装好matlab后键盘复制粘贴快捷键不能使用 解决办法
- FTI FormingSuite 2018 官方版下载附安装教程
- spring配置bean的细节二
- Tensorflow实例:实现GAN(生成对抗网)
- [区间DP] POJ 3186
- AES过程
- Python之旅
- 数据结构->二叉树的基本操作
- 斯坦福大学Tensorflow与深度学习实战课程
- 51nod 1172 Partial Sums V2 任意模数FFT
- 高级用法
- 程序员偷偷深爱的9个不良编程习惯
- python随机数
- SQL Server 返回结果集的几种方式