我需要实现登录到.NET Soap Web Service。此Web服务具有方法RSA。 Java Encryption .NET解密
AuthenticateUser(username, password)
并且密码应该用RSA公钥加密。下面我试图做的事:
public static final String PUBLIC = "q/9CujExqL6rsMMO22WWIotoXDCw5KEmGQJqL9UJEfoErwZ9ZCm3OwMTSlAMSfoXEMA04Y1rhfYC3MtU/7dYEoREfsvOPGDBWanTKyMzv2otCfiURyQoghEdkhv3ipQQaaErT7lfBKobJsdqJlvxo4PCOUas2Z6YpoMYgthzTiM=";
public static final String EXPONENT = "AQAB";
public static PublicKey getPublicKey() throws Exception{
byte[] modulusBytes = Base64.decode(PUBLIC, 0);
byte[] exponentBytes = Base64.decode(EXPONENT, 0);
BigInteger modulus = new BigInteger(1, (modulusBytes));
BigInteger exponent = new BigInteger(1, (exponentBytes));
RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public static byte[] encrypt(Key publicKey, String s) throws Exception{
byte[] byteData = s.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(byteData);
return encryptedData;
}
public static String arrayAsString (byte [] array){
String p = "";
for (int i = 0; i < array.length; i++) {
p += unsignedToBytes(array[i]);
if (i < array.length - 1)
p+= ",";
}
return p;
}
public static int unsignedToBytes(byte b) {
return b & 0xFF;
}
public static void main(String[] args){
PublicKey publicKey = getPublicKey();
byte [] encrypted = encode(publicKey, "passwordHere");
String pass = arrayAsString(encrypted);
webservice.AuthenticateUser("testAdmin", pass);
}
我也有从Web服务端的.NET代码
private static string publicKey = "<RSAKeyValue><Modulus>q/9CujExqL6rsMMO22WWIotoXDCw5KEmGQJqL9UJEfoErwZ9ZCm3OwMTSlAMSfoXEMA04Y1rhfYC3MtU/7dYEoREfsvOPGDBWanTKyMzv2otCfiURyQoghEdkhv3ipQQaaErT7lfBKobJsdqJlvxo4PCOUas2Z6YpoMYgthzTiM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
private static UnicodeEncoding _encoder = new UnicodeEncoding();
public static string Encrypt(string data)
{
var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(publicKey);
var dataToEncrypt = _encoder.GetBytes(data);
var encryptedByteArray = rsa.Encrypt(dataToEncrypt, false).ToArray();
var length = encryptedByteArray.Count();
var item = 0;
var sb = new StringBuilder();
foreach (var x in encryptedByteArray)
{
item++;
sb.Append(x);
if (item < length)
sb.Append(",");
}
return sb.ToString();
}
public static string Decrypt(string data)
{
var rsa = new RSACryptoServiceProvider();
var dataArray = data.Split(new char[] { ',' });
byte[] dataByte = new byte[dataArray.Length];
for (int i = 0; i < dataArray.Length; i++)
{
dataByte[i] = Convert.ToByte(dataArray[i]);
}
rsa.FromXmlString(privateKey);
var decryptedByte = rsa.Decrypt(dataByte, false);
return _encoder.GetString(decryptedByte);
}
是否有人有任何想法,我做错了什么?为什么Web Service总是返回我AuthenticateUserResponse {AuthenticateUserResult = false; }
你有没有试过调试你的web服务?服务端的Decrypt输出是否与客户端加密的数据相同?除此之外,我认为这里真正的问题是您正在推出自己的加密协议。我的建议是只能通过SSL访问web服务,这样可以缓解您现在使用的代码中的不安全感(比如没有重播保护)。 – Iridium
感谢您的回复。不幸的是,我无法访问web服务端,因为这是第三方web服务,我无法检查输出并且无法更改安全性。你是什么意思“你正在推出你自己的加密协议”? –