zoukankan      html  css  js  c++  java
  • 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下的可执行工具。

  • 相关阅读:
    Python函数式编程学习笔记
    DOS常用命令总结
    Python高级特性学习笔记
    Git bash使用中...
    《零基础入门学习Python》学习过程笔记【30模块中的函数,os模块,ospath模块中的函数(看了一点)】
    这两天将这段时间的python笔记常用知识复习了一遍...前天半夜吃了盘烤羊肉..得了急性肠炎
    《零基础入门学习Python》学习过程笔记【29对文件进行分割】(没看)
    《零基础入门学习Python》学习过程笔记【28文件】
    《零基础入门学习Python》学习过程笔记【27集合】
    用python写一个简单的用户登陆程序(要求写成函数)
  • 原文地址:https://www.cnblogs.com/zolo/p/5886368.html
Copyright © 2011-2022 走看看