Nodejs和java密钥的生成

Nodejs和java密钥的生成

Java代码:

public String encryption(String str)throws Exception{
		try {
			String KEY = "123456789";
			byte[] enCriptSHA1String = enCriptSHA1(str);//SHA-1   
		    String base64String = enBase64(enCriptSHA1String);//
		    System.out.println("1    "+base64String);
		    System.out.println("1.5    "+(str + "_" + base64String));
		    byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes());//DESede 
		    String base64StringRe = enBase64(enCrptString);
		    System.out.println("2    "+base64StringRe);
		    str=URLEncoder.encode(base64StringRe);
		    System.out.println("3    "+str);
		} catch (Exception e) {
			throw e;
		}
		return str;
	}
	public byte[] enCriptSHA1(String authenticator){
		//加密的方式
		final String Algorithm = "SHA-1";
		//实例MessageDigest对象
		MessageDigest md=null;
		byte[] encode=null;
		//加密数据转换成字节
		byte[] bt=authenticator.getBytes();
		try {
			//SHA-1加密
			md=MessageDigest.getInstance(Algorithm);
			md.update(bt);
			//二行制到字符串的转变
			encode=md.digest();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return encode;
	}
	public byte[] enCrpt(byte[] reqStr ,byte[] enkey){
		//加密的方式
		final String Algorithm = "DESede";
		//加密后的数据
		byte[] encoded = null;
		//根据密钥加密对象
		Cipher cipher = null;
		//得到密钥
		SecretKey secretKey = null;
		try {
			//得到密钥
			secretKey = getSecretKey(enkey,Algorithm);
			//加密
			cipher = Cipher.getInstance(Algorithm);
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			//得到解加密后的数据
			encoded = cipher.doFinal(reqStr);
		} catch (Exception e) {
			
		}
		return encoded;
	}

nodejs 代码:

function aesEncrypt(data) {
		 var cipher = crypto.createHash('sha1');
		 var encodeC = cipher.update(data).digest().toString('base64');
		 var ciphertwo = crypto.createCipher('des-ede',new Buffer('12345678'),0);
		 var endate = data+'_'+encodeC;
		 var en = ciphertwo.update(new Buffer(endate),'binary','base64')+ciphertwo.final('base64');
		 console.info("en: "+en+"   ");
         return en;
	};

以上分别是我java和nodejs加密写法,为什么得出的结果不一样呢请大神指导下,看看哪里有错。


6 回复

好的,我们可以对比并分析你的Java和Node.js代码,找出可能的原因,并提供改进后的代码。

Java 代码

public String encryption(String str) throws Exception {
    try {
        String KEY = "123456789";
        byte[] enCriptSHA1String = enCriptSHA1(str); // SHA-1
        String base64String = new String(Base64.getEncoder().encode(enCriptSHA1String), StandardCharsets.UTF_8);
        System.out.println("1    " + base64String);
        System.out.println("1.5    " + (str + "_" + base64String));
        byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes()); // DESede
        String base64StringRe = new String(Base64.getEncoder().encode(enCrptString), StandardCharsets.UTF_8);
        System.out.println("2    " + base64StringRe);
        str = URLEncoder.encode(base64StringRe, StandardCharsets.UTF_8.name());
        System.out.println("3    " + str);
    } catch (Exception e) {
        throw e;
    }
    return str;
}

public byte[] enCriptSHA1(String authenticator) {
    final String Algorithm = "SHA-1";
    MessageDigest md = null;
    byte[] encode = null;
    byte[] bt = authenticator.getBytes();
    try {
        md = MessageDigest.getInstance(Algorithm);
        md.update(bt);
        encode = md.digest();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return encode;
}

public byte[] enCrpt(byte[] reqStr, byte[] enkey) {
    final String Algorithm = "DESede";
    byte[] encoded = null;
    Cipher cipher = null;
    SecretKey secretKey = null;
    try {
        secretKey = new SecretKeySpec(enkey, Algorithm);
        cipher = Cipher.getInstance(Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        encoded = cipher.doFinal(reqStr);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return encoded;
}

Node.js 代码

const crypto = require('crypto');

function aesEncrypt(data) {
    const sha1 = crypto.createHash('sha1');
    const encodeC = sha1.update(data).digest().toString('base64');
    
    const desCipher = crypto.createCipher('des-ede', '12345678');
    const endate = data + '_' + encodeC;
    let en = desCipher.update(endate, 'utf8', 'base64') + desCipher.final('base64');
    
    console.info("en: " + en);
    return en;
}

分析与改进

  1. SHA-1 加密

    • 在Java中,enCriptSHA1方法直接返回了字节数组。
    • 在Node.js中,使用toString('base64')将字节数组转换为Base64字符串。确保在Java中也进行相同的转换。
  2. DESede 加密

    • Java中的enCrpt方法使用的是DESede算法。
    • Node.js中的createCipher方法也需要指定相同的算法。但是,Node.js的crypto库默认使用des-ede3,而不是des-ede。如果需要des-ede,可以考虑使用createCipheriv并手动设置参数。

改进后的Node.js 代码

const crypto = require('crypto');

function aesEncrypt(data) {
    const sha1 = crypto.createHash('sha1');
    const encodeC = sha1.update(data).digest().toString('base64');
    
    const desCipher = crypto.createCipheriv('des-ede3', Buffer.from('12345678'), ''); // 使用 'des-ede3' 和密钥
    const endate = data + '_' + encodeC;
    let en = desCipher.update(endate, 'utf8', 'base64') + desCipher.final('base64');
    
    console.info("en: " + en);
    return en;
}

通过上述改进,你可以确保Java和Node.js代码在处理SHA-1和DESede加密时的一致性。希望这能帮助你解决问题!


谢谢,这个我看过,好像不行。。。

你的 getSecretKey 方法在哪里? 贴了个小片段,想试验一下都不行。。。。

我也在这里卡了一段时间,后来各种尝试终于解决了:(不太懂这个网站应该怎么格式代码,代码贴的比较丑,见谅了;)

AESCrypt.js

var crypto = require('crypto');

var AESCrypt = {};

AESCrypt.decrypt = function(cryptkey, iv, encryptdata) { encryptdata = new Buffer(encryptdata, ‘base64’).toString(‘binary’); var decipher = crypto.createDecipheriv(‘aes-128-cbc’, cryptkey, iv); var decoded = decipher.update(encryptdata, ‘binary’, ‘utf8’);

decoded += decipher.final('utf8');
return decoded;

}

AESCrypt.encrypt = function(cryptkey, iv, cleardata) { var encipher = crypto.createCipheriv(‘aes-128-cbc’, cryptkey, iv); var encryptdata = encipher.update(cleardata, ‘utf8’, ‘binary’); encryptdata += encipher.final(‘binary’); var encode_encryptdata = new Buffer(encryptdata, ‘binary’).toString(‘base64’); return encode_encryptdata; }

module.exports = AESCrypt;

AESCryptTest.js

var AESCrypt = require('./AESCrypt');
var cryptkey   = new Buffer('1234567890123456','utf-8'),
iv         = new Buffer('00000000000000000000000000000000','hex').toString('utf-8');

var obj = {
    a:'1',
    b:'2'
}

var objStr = JSON.stringify(obj);
var encStr = AESCrypt.encrypt(cryptkey, iv, objStr);
var decStr = AESCrypt.decrypt(cryptkey, iv, encStr);
var decObj = JSON.parse(decStr);
console.log(decObj);

在你的问题中,Java 和 Node.js 的加密实现存在一些差异,导致最终结果不同。以下是针对你提供的代码进行的修改,以确保两者能够一致地执行加密操作。

Java 代码

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.util.Base64;

public String encryption(String str) throws Exception {
    try {
        String KEY = "123456789";
        byte[] enCriptSHA1String = enCriptSHA1(str); // SHA-1
        String base64String = Base64.getEncoder().encodeToString(enCriptSHA1String); // base64 encode
        System.out.println("1    " + base64String);
        System.out.println("1.5    " + (str + "_" + base64String));
        byte[] enCrptString = enCrpt((str + "_" + base64String).getBytes(), KEY.getBytes()); // DESede
        String base64StringRe = Base64.getEncoder().encodeToString(enCrptString);
        System.out.println("2    " + base64StringRe);
        str = URLEncoder.encode(base64StringRe, "UTF-8");
        System.out.println("3    " + str);
    } catch (Exception e) {
        throw e;
    }
    return str;
}

public byte[] enCriptSHA1(String authenticator) {
    final String Algorithm = "SHA-1";
    MessageDigest md = null;
    byte[] encode = null;
    byte[] bt = authenticator.getBytes();
    try {
        md = MessageDigest.getInstance(Algorithm);
        md.update(bt);
        encode = md.digest();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return encode;
}

public byte[] enCrpt(byte[] reqStr, byte[] enkey) {
    final String Algorithm = "DESede/ECB/PKCS5Padding";
    byte[] encoded = null;
    Cipher cipher = null;
    SecretKeySpec secretKey = new SecretKeySpec(enkey, Algorithm);
    try {
        cipher = Cipher.getInstance(Algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        encoded = cipher.doFinal(reqStr);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return encoded;
}

Node.js 代码

const crypto = require('crypto');

function aesEncrypt(data) {
    const hash = crypto.createHash('sha1').update(data).digest();
    const base64Sha1 = hash.toString('base64');
    
    const key = crypto.scryptSync('12345678', '', 24); // Generate 24-byte key for 3DES
    const cipher = crypto.createCipheriv('des-ede3', key, '');
    let encrypted = cipher.update(data + '_' + base64Sha1, 'utf8', 'base64') + cipher.final('base64');
    
    console.info("en: " + encrypted);
    return encrypted;
}

// Test the function
aesEncrypt('test');  // Replace 'test' with your input string

主要修改点

  1. Java:

    • 使用 Base64.getEncoder().encodeToString 进行 Base64 编码。
    • 确保 enCrpt 方法使用正确的 DESede 加密模式(如 DESede/ECB/PKCS5Padding)。
  2. Node.js:

    • 使用 crypto.scryptSync 生成 24 字节的密钥,适合 des-ede3 加密算法。
    • 使用 createCipheriv 方法进行初始化向量(IV)设置,尽管这里的 IV 是空的,但这是标准做法。

通过这些修改,可以确保 Java 和 Node.js 的加密结果一致。

回到顶部