银联支付接口使用rsa 数据加密。明文,密钥,都是16进制的字符串,加密结果和对方给的小工具加密的结果不一样 小工具rsatools.exe 求大神指导 代码如下
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class test {
/**
* 加密
*
* @param key
* 加密的密钥
* @param data
* 待加密的明文数据
* @return 加密后的数据
* @throws Exception
*/
public byte[] encrypt(Key key, byte[] data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA",
new BouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE, key);
// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127
// byte,加密后为128个byte;
// 因此共有2个加密块,第一个127 byte第二个为1个byte
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
int leavedSize = data.length % blockSize;
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
: data.length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 0;
while (data.length - i * blockSize > 0) {
if (data.length - i * blockSize > blockSize)
cipher.doFinal(data, i * blockSize, blockSize, raw, i
* outputSize);
else
cipher.doFinal(data, i * blockSize, data.length - i
* blockSize, raw, i * outputSize);
// 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中
// ,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
i++;
}
return raw;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 解密
*
* @param key
* 解密的密钥
* @param raw
* 已经加密的数据
* @return 解密后的明文
* @throws Exception
*/
public byte[] decrypt(Key key, byte[] raw) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA",
new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(cipher.DECRYPT_MODE, key);
int blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
j++;
}
return bout.toByteArray();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 测试
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
RSAUtil rsa = new RSAUtil();
String modeHex = "BB83CB428FF41B61762FB8A34041EF8B897301DC4DB84CBD60FEBFC244260B7CC3D57925591970028BB466E13C5A51650213DB7566A78453EA55D725A9B78884A99FD8B1530499D08F3D8CF078CDA4346395CCCA8379E814559E3F6A7DB851C9FCA1FC5A0D3983C637E33B02DA65DF139428C19D9EE2AD8F9A15663E984B166B";
String messageg = "06111111FFFFFFFFA1D93F0C1C682F1836B7E97CC0A8D37363237EA630383632323235383030303030303030303030303120202020202020202036323232353830303030303030303030303032202020202020202020303531323234363536343836352020343231303333202020202020202020202020202020202020202020";
String exponentHex = "010001";
KeyFactory factory = KeyFactory.getInstance("RSA", new BouncyCastleProvider());
BigInteger n = new BigInteger(modeHex, 16);
BigInteger e = new BigInteger(exponentHex, 16);
RSAPublicKeySpec spec = new RSAPublicKeySpec(n, e);
RSAPublicKey pub = (RSAPublicKey) factory.generatePublic(spec);
byte[] mi = rsa.encrypt(pub, messageg.getBytes("GB2312"));
String result1 = new String(Hex.encodeHex(mi));
System.out.println("加密后==" + result1);
}
}