首页 新闻 会员 周边

16进制公钥,PHP RSA验证数据问题,跪求大神来解答,我所有的园豆都给你???!!!!

0
悬赏园豆:200 [已解决问题] 解决于 2016-10-31 16:36

问题是这样的,我们公司和其他公司会有一个数据的交互。当参数来到我们这里的时候需要进行各验证签名。就是验签,我们使用的是RSA方式,PHP语言来处理。但是对方公司使用JAVA来做,本来这不是问题,但是他们给的公钥和私钥都是16进制的。类似于如下

//十六进制公钥

30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100845dfd18910026e2453710a2b2a4245ec0e019df083ac5e705cb02da01aff17acdd57daeef598c34d19d624d0e2315a14f6d11b9a8be46b4ba1a9b485d568c42a66ae3eb3b325aba537ed1dbf5fae3e1b74243f8f0f9b65ba3f72d41fe7a0354f401d4160b409c320c8591d2211c4a1e147276e4fdf2c488616872e67876875102030100010281804d0d8175b982c31fd876d382424776bc89be6a910073661cb3ac97be5c5915530d5b07ccbb9bff1808257bc1ab4715224fe007ff7191420b9682427e7f87102225e04b86a1f2edaf8e3be363d19cc57da43a5113f141d850b05119386dda4234e3cff902ae43402eef8106275484a82367c844920a96cfb0825e3667944e9339024100f21ca40df167a

 

我平日里和其他公司交互时候使用的公钥如下

//平日的公钥如

-----BEGIN PUBLIC KEY-----  MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC19+3Zkg8ko4S7XeAjGl2ps8dE  VGx2prFAAsq9OeNjvI4zbUG2iw7fvk02VZuilYyspB/MR1nMEWreVj21FdnN/szI  lC/stptlNMtmkZ28jv8QVvls8O2Zp97qDxSWbYwZFT1nmQVK1uSZV7wMEldWTSlF  cLuOXoFGGXndO9062QIDAQAB  

-----END PUBLIC KEY-----

 

问题来了我应该如何处理呢,先把16进制转换成普通的格式,我在网上查到的资料说是根本转换不了,但是对方公司也是用PHP可以做的。

跪求大神帮帮忙吧 

捷克轩的主页 捷克轩 | 初学一级 | 园豆:26
提问于:2015-10-16 16:16
< >
分享
最佳答案
1

不要着急,慢慢查,总会找到解决方法的!

收获园豆:200
晓菜鸟 | 老鸟四级 |园豆:2594 | 2015-10-17 16:05
其他回答(6)
0

你该搞明白他的公钥是怎么来的,你才好去解析

稳稳的河 | 园豆:4216 (老鸟四级) | 2015-10-16 16:52

import java.security.KeyPairGenerator; 他的公钥是通过这个JAVA程序生成的是RSA方法,在生成之后用了一个16进制的转换

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-16 16:59


public class RSA {

private static final char[] HEX_LOOKUP_STRING = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f'};

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

/**
* 将字节数组转换为16进制字符串的形式.
*/
public static final String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);

for (int i = 0; i < bcd.length; i++) {
s.append(HEX_LOOKUP_STRING[(bcd[i] >>> 4) & 0x0f]);
s.append(HEX_LOOKUP_STRING[bcd[i] & 0x0f]);
}

return s.toString();
}

/**
* 将16进制字符串还原为字节数组.
*/
public static final byte[] hexStrToBytes(String s) {
byte[] bytes;

bytes = new byte[s.length() / 2];

for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}

return bytes;
}

/**
* 得到私钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}

/**
* 得到公钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}

/**
* 本方法使用SHA1withRSA签名算法产生签名
*
* @param String priKey 签名时使用的私钥(16进制编码)
* @param String src 签名的原字符串
* @return String 签名的返回结果(16进制编码)。当产生签名出错的时候,返回null。
* @throws PayException
*/
public static String sign(PrivateKey privateKey, String src) throws Exception {
Signature sigEng = Signature.getInstance(SIGN_ALGORITHMS);
sigEng.initSign(privateKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] signature = sigEng.sign();
return bytesToHexStr(signature);
}

/**
* 本方法使用SHA1withRSA签名算法验证签名
*
* @param String pubKey 验证签名时使用的公钥(16进制编码)
* @param String sign 签名结果(16进制编码)
* @param String src 签名的原字符串
* @throws PayException 验证失败时抛出异常
*/
public static final void verify(PublicKey publicKey, String sign, String src) throws Exception {
Signature sigEng = Signature.getInstance("SHA1withRSA");
sigEng.initVerify(publicKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] sign1 = hexStrToBytes(sign);
if (!sigEng.verify(sign1)) {
throw new Exception("verify failed");
}
}

/**
* 本方法用于产生1024位RSA公私钥对。
*
* @return 私钥、公钥
*/
private static String[] genRSAKeyPair() throws Exception {
KeyPairGenerator rsaKeyGen = null;
KeyPair rsaKeyPair = null;
System.out.println("Generating a pair of RSA key ... ");
rsaKeyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
random.setSeed(("" + System.currentTimeMillis() * Math.random() * Math.random()).getBytes());
rsaKeyGen.initialize(1024, random);
rsaKeyPair = rsaKeyGen.genKeyPair();
PublicKey rsaPublic = rsaKeyPair.getPublic();
PrivateKey rsaPrivate = rsaKeyPair.getPrivate();

String privateAndPublic[] = new String[2];
privateAndPublic[0] = bytesToHexStr(rsaPrivate.getEncoded());
privateAndPublic[1] = bytesToHexStr(rsaPublic.getEncoded());
System.out.println("私钥:" + privateAndPublic[0]);
System.out.println("公钥:" + privateAndPublic[1]);
System.out.println("1024-bit RSA key GENERATED.");

return privateAndPublic;
}

/**
* 请在java工程中跑此main函数
*
* @param args
*/
public static void main(String[] args) {
try {
String[] privateAndPublic = genRSAKeyPair();

PrivateKey privateKey = getPrivateKey(privateAndPublic[0]);
PublicKey publicKey = getPublicKey(privateAndPublic[1]);

String signSrc = URLEncoder.encode(
"urstestc@163.com1您好20101227105117201012271131591203.86.63.98203.86.63.9854416", "UTF-8");
String sign = sign(privateKey, signSrc);
System.out.println("原始串:" + signSrc);
System.out.println("签名:" + sign);
verify(publicKey, sign, signSrc);
System.out.println("验证签名成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-19 10:08
0

一给就是200分,有分任性!

Firen | 园豆:5385 (大侠五级) | 2015-10-16 17:17

我是着急啊 希望有人来帮忙啊

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-16 17:22
0

你让对方把16进制转换的算法告诉你,你再按他们的规则把收到的字符串逆转回去就可以了。

I,Robot | 园豆:9783 (大侠五级) | 2015-10-17 05:10


public class RSA {

private static final char[] HEX_LOOKUP_STRING = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f'};

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

/**
* 将字节数组转换为16进制字符串的形式.
*/
public static final String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);

for (int i = 0; i < bcd.length; i++) {
s.append(HEX_LOOKUP_STRING[(bcd[i] >>> 4) & 0x0f]);
s.append(HEX_LOOKUP_STRING[bcd[i] & 0x0f]);
}

return s.toString();
}

/**
* 将16进制字符串还原为字节数组.
*/
public static final byte[] hexStrToBytes(String s) {
byte[] bytes;

bytes = new byte[s.length() / 2];

for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}

return bytes;
}

/**
* 得到私钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}

/**
* 得到公钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}

/**
* 本方法使用SHA1withRSA签名算法产生签名
*
* @param String priKey 签名时使用的私钥(16进制编码)
* @param String src 签名的原字符串
* @return String 签名的返回结果(16进制编码)。当产生签名出错的时候,返回null。
* @throws PayException
*/
public static String sign(PrivateKey privateKey, String src) throws Exception {
Signature sigEng = Signature.getInstance(SIGN_ALGORITHMS);
sigEng.initSign(privateKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] signature = sigEng.sign();
return bytesToHexStr(signature);
}

/**
* 本方法使用SHA1withRSA签名算法验证签名
*
* @param String pubKey 验证签名时使用的公钥(16进制编码)
* @param String sign 签名结果(16进制编码)
* @param String src 签名的原字符串
* @throws PayException 验证失败时抛出异常
*/
public static final void verify(PublicKey publicKey, String sign, String src) throws Exception {
Signature sigEng = Signature.getInstance("SHA1withRSA");
sigEng.initVerify(publicKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] sign1 = hexStrToBytes(sign);
if (!sigEng.verify(sign1)) {
throw new Exception("verify failed");
}
}

/**
* 本方法用于产生1024位RSA公私钥对。
*
* @return 私钥、公钥
*/
private static String[] genRSAKeyPair() throws Exception {
KeyPairGenerator rsaKeyGen = null;
KeyPair rsaKeyPair = null;
System.out.println("Generating a pair of RSA key ... ");
rsaKeyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
random.setSeed(("" + System.currentTimeMillis() * Math.random() * Math.random()).getBytes());
rsaKeyGen.initialize(1024, random);
rsaKeyPair = rsaKeyGen.genKeyPair();
PublicKey rsaPublic = rsaKeyPair.getPublic();
PrivateKey rsaPrivate = rsaKeyPair.getPrivate();

String privateAndPublic[] = new String[2];
privateAndPublic[0] = bytesToHexStr(rsaPrivate.getEncoded());
privateAndPublic[1] = bytesToHexStr(rsaPublic.getEncoded());
System.out.println("私钥:" + privateAndPublic[0]);
System.out.println("公钥:" + privateAndPublic[1]);
System.out.println("1024-bit RSA key GENERATED.");

return privateAndPublic;
}

/**
* 请在java工程中跑此main函数
*
* @param args
*/
public static void main(String[] args) {
try {
String[] privateAndPublic = genRSAKeyPair();

PrivateKey privateKey = getPrivateKey(privateAndPublic[0]);
PublicKey publicKey = getPublicKey(privateAndPublic[1]);

String signSrc = URLEncoder.encode(
"urstestc@163.com1您好20101227105117201012271131591203.86.63.98203.86.63.9854416", "UTF-8");
String sign = sign(privateKey, signSrc);
System.out.println("原始串:" + signSrc);
System.out.println("签名:" + sign);
verify(publicKey, sign, signSrc);
System.out.println("验证签名成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}

这是生成的方法

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-19 10:08
0

最简单的方法,直接和对方沟通。。。

幻天芒 | 园豆:37175 (高人七级) | 2015-10-17 08:54
0

直接与对方沟通,看看人家的原理,

夜空下的男子 | 园豆:31 (初学一级) | 2015-10-17 16:45

 他是用JAVA生成的

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-19 09:44


public class RSA {

private static final char[] HEX_LOOKUP_STRING = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f'};

public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

/**
* 将字节数组转换为16进制字符串的形式.
*/
public static final String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);

for (int i = 0; i < bcd.length; i++) {
s.append(HEX_LOOKUP_STRING[(bcd[i] >>> 4) & 0x0f]);
s.append(HEX_LOOKUP_STRING[bcd[i] & 0x0f]);
}

return s.toString();
}

/**
* 将16进制字符串还原为字节数组.
*/
public static final byte[] hexStrToBytes(String s) {
byte[] bytes;

bytes = new byte[s.length() / 2];

for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}

return bytes;
}

/**
* 得到私钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}

/**
* 得到公钥对象
*
* @param key 密钥字符串(经过16进制编码)
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = hexStrToBytes(key.trim());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}

/**
* 本方法使用SHA1withRSA签名算法产生签名
*
* @param String priKey 签名时使用的私钥(16进制编码)
* @param String src 签名的原字符串
* @return String 签名的返回结果(16进制编码)。当产生签名出错的时候,返回null。
* @throws PayException
*/
public static String sign(PrivateKey privateKey, String src) throws Exception {
Signature sigEng = Signature.getInstance(SIGN_ALGORITHMS);
sigEng.initSign(privateKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] signature = sigEng.sign();
return bytesToHexStr(signature);
}

/**
* 本方法使用SHA1withRSA签名算法验证签名
*
* @param String pubKey 验证签名时使用的公钥(16进制编码)
* @param String sign 签名结果(16进制编码)
* @param String src 签名的原字符串
* @throws PayException 验证失败时抛出异常
*/
public static final void verify(PublicKey publicKey, String sign, String src) throws Exception {
Signature sigEng = Signature.getInstance("SHA1withRSA");
sigEng.initVerify(publicKey);
sigEng.update(src.getBytes("UTF-8"));
byte[] sign1 = hexStrToBytes(sign);
if (!sigEng.verify(sign1)) {
throw new Exception("verify failed");
}
}

/**
* 本方法用于产生1024位RSA公私钥对。
*
* @return 私钥、公钥
*/
private static String[] genRSAKeyPair() throws Exception {
KeyPairGenerator rsaKeyGen = null;
KeyPair rsaKeyPair = null;
System.out.println("Generating a pair of RSA key ... ");
rsaKeyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = new SecureRandom();
random.setSeed(("" + System.currentTimeMillis() * Math.random() * Math.random()).getBytes());
rsaKeyGen.initialize(1024, random);
rsaKeyPair = rsaKeyGen.genKeyPair();
PublicKey rsaPublic = rsaKeyPair.getPublic();
PrivateKey rsaPrivate = rsaKeyPair.getPrivate();

String privateAndPublic[] = new String[2];
privateAndPublic[0] = bytesToHexStr(rsaPrivate.getEncoded());
privateAndPublic[1] = bytesToHexStr(rsaPublic.getEncoded());
System.out.println("私钥:" + privateAndPublic[0]);
System.out.println("公钥:" + privateAndPublic[1]);
System.out.println("1024-bit RSA key GENERATED.");

return privateAndPublic;
}

/**
* 请在java工程中跑此main函数
*
* @param args
*/
public static void main(String[] args) {
try {
String[] privateAndPublic = genRSAKeyPair();

PrivateKey privateKey = getPrivateKey(privateAndPublic[0]);
PublicKey publicKey = getPublicKey(privateAndPublic[1]);

String signSrc = URLEncoder.encode(
"urstestc@163.com1您好20101227105117201012271131591203.86.63.98203.86.63.9854416", "UTF-8");
String sign = sign(privateKey, signSrc);
System.out.println("原始串:" + signSrc);
System.out.println("签名:" + sign);
verify(publicKey, sign, signSrc);
System.out.println("验证签名成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}

支持(0) 反对(0) 捷克轩 | 园豆:26 (初学一级) | 2015-10-19 10:08
0

厄  算法还关系语言么? 同一个算法,Java生成的公钥和PhP生成的公钥是一样的吧。。。

 

我也不懂,来学习。

小刺猬001 | 园豆:660 (小虾三级) | 2015-12-01 15:37
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册