您现在的位置是:网站首页> Go语言

go与java互用的AES实现

摘要

终于实现了go与java互用的AES算法实现。基于go可以编译windows与linux下的命令行工具,十分方便。

Java源码

import java.security.GeneralSecurityException;

import java.util.Arrays;


import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;


public class AES {


public static byte[] encrypt(String key, byte[] origData) throws GeneralSecurityException {


byte[] keyBytes = getKeyBytes(key);

byte[] buf = new byte[16];

System.arraycopy(keyBytes, 0, buf, 0, keyBytes.length > buf.length ? keyBytes.length : buf.length);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(buf, "AES"), new IvParameterSpec(keyBytes));

return cipher.doFinal(origData);


}


public static byte[] decrypt(String key, byte[] crypted) throws GeneralSecurityException {

byte[] keyBytes = getKeyBytes(key);

byte[] buf = new byte[16];

System.arraycopy(keyBytes, 0, buf, 0, keyBytes.length > buf.length ? keyBytes.length : buf.length);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(buf, "AES"), new IvParameterSpec(keyBytes));

return cipher.doFinal(crypted);

}


private static byte[] getKeyBytes(String key) {

byte[] bytes = key.getBytes();

return bytes.length == 16 ? bytes : Arrays.copyOf(bytes, 16);

}


public static String encrypt(String key, String val) throws GeneralSecurityException {

byte[] origData = val.getBytes();

byte[] crypted = encrypt(key, origData);

return Base64.Encoder.RFC4648_URLSAFE.encodeToString(crypted);

}


public static String decrypt(String key, String val) throws GeneralSecurityException {

byte[] crypted = Base64.Decoder.RFC4648_URLSAFE.decode(val);

byte[] origData = decrypt(key, crypted);

return new String(origData);

}


/**

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {


if (args.length != 3) {

System.err.print("Usage: java AES (-e|-d) <key> <content>");

}

if ("-e".equals(args[0])) {

System.out.println(encrypt(args[1], args[2]));

} else if ("-d".equals(args[0])) {

System.out.println(decrypt(args[1], args[2]));

} else {

System.err.print("Usage: java AES (-e|-d) <key> <content>");

}

}


}

Go源码

package main


import (

"bytes"

"crypto/aes"

"crypto/cipher"

"encoding/base64"

"os"

)


func getKeyBytes(key string) []byte {

keyBytes := []byte(key)

switch l := len(keyBytes); {

case l < 16:

keyBytes = append(keyBytes, make([]byte, 16-l)...)

case l > 16:

keyBytes = keyBytes[:16]

}

return keyBytes

}


func encrypt(key string, origData []byte) ([]byte, error) {

keyBytes := getKeyBytes(key)

block, err := aes.NewCipher(keyBytes)

if err != nil {

return nil, err

}

blockSize := block.BlockSize()

origData = PKCS5Padding(origData, blockSize)

blockMode := cipher.NewCBCEncrypter(block, keyBytes[:blockSize])

crypted := make([]byte, len(origData))

blockMode.CryptBlocks(crypted, origData)

return crypted, nil

}


func decrpt(key string, crypted []byte) ([]byte, error) {

keyBytes := getKeyBytes(key)

block, err := aes.NewCipher(keyBytes)

if err != nil {

return nil, err

}

blockSize := block.BlockSize()

blockMode := cipher.NewCBCDecrypter(block, keyBytes[:blockSize])

origData := make([]byte, len(crypted))

blockMode.CryptBlocks(origData, crypted)

origData = PKCS5UnPadding(origData)

return origData, nil

}


func PKCS5Padding(ciphertext []byte, blockSize int) []byte {

padding := blockSize - len(ciphertext)%blockSize

padtext := bytes.Repeat([]byte{byte(padding)}, padding)

return append(ciphertext, padtext...)

}


func PKCS5UnPadding(origData []byte) []byte {

length := len(origData)

unpadding := int(origData[length-1])

return origData[:(length - unpadding)]

}


func Encrypt(key string, val string) (string, error) {

origData := []byte(val)

crypted, err := encrypt(key, origData)

if err != nil {

return "", err

}

return base64.URLEncoding.EncodeToString(crypted), nil

}


func Decrypt(key string, val string) (string, error) {

crypted, err := base64.URLEncoding.DecodeString(val)

if err != nil {

return "", err

}

origData, err := decrpt(key, crypted)

if err != nil {

return "", err

}

return string(origData), nil

}


func main() {


argc := len(os.Args)

if argc != 4 {

os.Stdout.WriteString("usage: AES (-e|-d) <key> <content>")

return

}


switch os.Args[1] {

case "-e":

ret, err := Encrypt(os.Args[2], os.Args[3])

if err != nil {

os.Stderr.WriteString(err.Error())

os.Exit(1)

}

println(ret)

case "-d":

ret, err := Decrypt(os.Args[2], os.Args[3])

if err != nil {

os.Stderr.WriteString(err.Error())

os.Exit(1)

}

println(ret)

default:

os.Stdout.WriteString("usage: AES (-e|-d) <key> <content>")

}

}


使用go可以编译Windows与Linux下的可执行工具。




Top