V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
hilow
V2EX  ›  问与答

Java 中的 AES SHA1PRNG 如何用 golang 实现?

  •  1
     
  •   hilow · 2018-06-01 12:37:44 +08:00 · 3907 次点击
    这是一个创建于 2365 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    /**
     *
     * AES CBC 256 位加密
     * @param content 加密内容字节数组
     * @param keyBytes 加密字节数组
     * @param iv 加密向量字节数组
     * @param encryptLength 仅支持 128、256 长度
     * @return 解密后字节内容
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws InvalidAlgorithmParameterException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public static byte[] encryptAESCBC( byte[] content, byte[] keyBytes,byte[] iv, int encryptLength )
    {
    
    	KeyGenerator	keyGenerator	= KeyGenerator.getInstance( "AES" );
    	SecureRandom	secureRandom	= SecureRandom.getInstance( "SHA1PRNG" );
    	secureRandom.setSeed( keyBytes );
    	keyGenerator.init( encryptLength, secureRandom );
    	SecretKey	key	= keyGenerator.generateKey();  
    	// 以上应该是使用任意长度的 keyBytes,生成指定长度为 encryptLength 的 key
    	// 后面再使用 AES/CBC/PKCS5Padding 算法,对 content 加密,加密角度是上面生成的固定长度的 key
    	// 我的主要疑问就在这里,  如何用 golang 生成与 keyGenerator.generateKey() 一样的 key 呢?
    
    
    	Cipher		cipher	= Cipher.getInstance( "AES/CBC/PKCS5Padding" );
    	cipher.init( Cipher.ENCRYPT_MODE, key, new IvParameterSpec( iv ) );
    	byte[] result = cipher.doFinal( content );
    	return(result);
    }
    
    
    第 1 条附言  ·  2018-06-03 20:04:14 +08:00

    用下面的 golang 代码模拟出 128 bit / 32 byte 的生成方案了 但超过 160 bit / 20 byte 就不行了

    
    // 模拟 Java 接口 generatorKey()
    // 目前 encryptLength 仅支持 128bit 长度
    // 因为 SHA1() 返回的长度固定为 20byte 160bit 
    // 所以 encryptLength 超过这个长度,就无法生成了
    // 因为不知道 java 中 AES SHA1PRNG 的生成逻辑
    func AESSHA1PRNG(keyBytes []byte,  encryptLength int) ([]byte, *exterror.Error) {
    	hashs := SHA1(SHA1(keyBytes))
    	maxLen := len(hashs)
    	realLen := encryptLength/8
    	if realLen > maxLen {
    		return nil, exterror.New1(fmt.Errorf("Not Support %d, Only Support Lower then %d [% x]", realLen, maxLen, hashs))
    	}
    
    	return hashs[0:realLen], nil
    }
    
    func SHA1(data []byte) []byte {
    	h := sha1.New()
    	h.Write(data)
    	return h.Sum(nil)
    }
    
    
    2 条回复    2018-06-03 20:10:57 +08:00
    a7a2
        1
    a7a2  
       2018-06-01 13:09:20 +08:00
    hilow
        2
    hilow  
    OP
       2018-06-03 20:10:57 +08:00
    @a7a2 谢了
    但我主要疑问不是如何加密,是如何生成加密时所用的 key
    java 中 AES SHA1PRNG 的生成逻辑是个黑盒吗?还是有什么标准可以参考?
    而且 keyBytes 固定时,在 jdk 1.7 时,这个操作返回的 key,每次都随机;
    我更新了 jdk 10 后,返回的 key 才固定下来。真把我搞晕了。

    [hi@hi javaapi]$ java -version
    java version "10.0.1" 2018-04-17
    Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
    Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2395 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:09 · PVG 00:09 · LAX 08:09 · JFK 11:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.