在java中发送rc4加密api调用
我尝试使用以下步骤在java中进行api调用:在java中发送rc4加密api调用,java,php,encryption,Java,Php,Encryption,我尝试使用以下步骤在java中进行api调用: json编码 RC4加密 base64编码 我目前在php中使用相同的系统,并且其工作正常: $enc_request = base64_encode(openssl_encrypt(json_encode($request_params), "rc4", $this->_app_key)); 但是当我在java中使用相同的系统时,结果并不像预期的那样。这是我的密码: //json encoding JSONObject obj = new
$enc_request = base64_encode(openssl_encrypt(json_encode($request_params), "rc4", $this->_app_key));
但是当我在java中使用相同的系统时,结果并不像预期的那样。这是我的密码:
//json encoding
JSONObject obj = new JSONObject();
obj.put("email", username);
obj.put("password", password);
obj.put("action", "login");
//function to encode base64
private String getBase64Encoded(String encryptedJsonString)
{
byte[] encoded = Base64.encodeBase64(encryptedJsonString.getBytes());
String encodedString = new String(encoded);
return encodedString;
}
//function to encrypt in RC4
private String getRC4EncryptedString2(String string, String key) throws Exception
{
Cipher cipher = Cipher.getInstance("RC4");
SecretKeySpec rc4Key = new SecretKeySpec(key.getBytes(), "RC4");
cipher.init(Cipher.ENCRYPT_MODE, rc4Key);
byte[] cipherText = cipher.update(string.getBytes());
return new String(cipherText);
}
我能够识别RC4加密之前的问题,该加密没有返回与php版本相同的结果
我已经为此奋斗了两天了。我希望我没有错过任何愚蠢的事情,因为这应该是直截了当的
谢谢您应该使用
字节[]
而不是字符串
来保存中间字节数组值。String
用于文本,而不是原始数据,它将尝试使用系统的默认字符集将字节解码为字符数据(至少单个参数String
构造函数会这样做)。与String.getBytes()相同
只需直接从getRC4EncryptedString2()
返回cipherText
,并将其直接传递到getBase64Encoded()
。这些编码器在字节数组上运行是有原因的,而这个原因并不是为了让您可以通过对中间的数据应用字符编码来篡改数据
传递给getRC4EncryptedString2()
的密钥也是如此。至少要使用String.getBytes(“ISO-8859-1”)
或其他东西(假设您的密钥实际上是文本,而不是另一个乱码字节数组)。无参数版本的getBytes()
返回使用系统默认字符集编码的文本,但不能保证该字符集是您想要的
这也适用于从base 64编码器返回的字符串。我不知道您使用的是什么base 64编码器,但请确保为字符串
构造函数指定字符集。很可能您会没事,这完全是巧合,但在转换为字符串和原始字节时,您应该始终指定一个字符集。当然,这是假设Base64编码器返回文本,而不是0-63范围内的字节
这里的要点是,您不能只是将字符串
来回转换为字节[]
。字符串
用于文本,其表示形式为字节[]
取决于字符编码。您应该使用字节[]
而不是字符串
来保存中间字节数组值。String
用于文本,而不是原始数据,它将尝试使用系统的默认字符集将字节解码为字符数据(至少单个参数String
构造函数会这样做)。与String.getBytes()相同
只需直接从getRC4EncryptedString2()
返回cipherText
,并将其直接传递到getBase64Encoded()
。这些编码器在字节数组上运行是有原因的,而这个原因并不是为了让您可以通过对中间的数据应用字符编码来篡改数据
传递给getRC4EncryptedString2()
的密钥也是如此。至少要使用String.getBytes(“ISO-8859-1”)
或其他东西(假设您的密钥实际上是文本,而不是另一个乱码字节数组)。无参数版本的getBytes()
返回使用系统默认字符集编码的文本,但不能保证该字符集是您想要的
这也适用于从base 64编码器返回的字符串。我不知道您使用的是什么base 64编码器,但请确保为字符串
构造函数指定字符集。很可能您会没事,这完全是巧合,但在转换为字符串和原始字节时,您应该始终指定一个字符集。当然,这是假设Base64编码器返回文本,而不是0-63范围内的字节
这里的要点是,您不能只是将字符串
来回转换为字节[]
。字符串
用于文本,其表示形式为字节[]
取决于字符编码。我可以使用以下代码实现这一点。希望这有帮助
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.DecoderException;
import org.bouncycastle.util.encoders.Hex;
import org.json.JSONException;
import org.json.JSONObject;
public class RC4Algo {
public static void main(String args[])throws IOException, NoSuchAlgorithmException, DecoderException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, JSONException
{
decryptRC4();
}
static String decryptRC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, JSONException{
//byte[] plainBytes = "testString".getBytes();
//json encoding
JSONObject obj = new JSONObject();
obj.put("email", "username");
obj.put("password", "password");
obj.put("action", "login");
byte [] plainBytes = obj.toString().getBytes();
String hashedKey = hashedData("thisismysecretkey");
//Generate a new key using KeyGenerator
/*KeyGenerator rc4KeyGenerator = KeyGenerator.getInstance("RC4");
SecretKey key = rc4KeyGenerator.generateKey();*/
Key key = new SecretKeySpec(Hex.decode(hashedKey), "RC4");
// Create Cipher instance and initialize it to encrytion mode
Cipher cipher = Cipher.getInstance("RC4"); // Transformation of the algorithm
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherBytes = cipher.doFinal(plainBytes);
String encoded = encodeBase64(cipherBytes);
String decoded = decodeBase64(encoded);
// Reinitialize the Cipher to decryption mode
cipher.init(Cipher.DECRYPT_MODE,key, cipher.getParameters());
byte[] plainBytesDecrypted = cipher.doFinal(Hex.decode(decoded));
System.out.println("Decrypted Data : "+new String(plainBytesDecrypted));
return new String(plainBytesDecrypted);
}
static String decodeBase64(String encodedData){
byte[] b = Base64.getDecoder().decode(encodedData);
String decodedData = DatatypeConverter.printHexBinary(b);
return decodedData;
}
static String encodeBase64(byte[] data){
byte[] b = Base64.getEncoder().encode(data);
String encodedData = new String(b);
/*String encodedData = DatatypeConverter.printHexBinary(b);*/
return encodedData;
}
static String hashedData(String key) throws NoSuchAlgorithmException{
String password = key;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
//convert the byte to hex format method 2
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
import java.io.IOException;
导入java.security.invalidalgorithParameterException;
导入java.security.InvalidKeyException;
导入java.security.Key;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入java.util.Base64;
导入javax.crypto.BadPaddingException;
导入javax.crypto.Cipher;
导入javax.crypto.IllegalBlockSizeException;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.spec.SecretKeySpec;
导入javax.xml.bind.DatatypeConverter;
导入org.apache.commons.codec.DecoderException;
导入org.bouncycastle.util.encoders.Hex;
导入org.json.JSONException;
导入org.json.JSONObject;
公共类RC4Algo{
公共静态void main(字符串参数[])抛出IOException、NoSuchAlgorithmException、DecodeException、InvalidKeyException、NoSuchPaddingException、IllegalBlockSizeException、BadPaddingException、InvalidAlgorithmParameterException、JSONException
{
解密RC4();
}
静态字符串decryptRC4()抛出NoSuchAlgorithmException、NoSuchPaddingException、InvalidKeyException、IllegalBlockSizeException、BadPaddingException、InvalidGorthmParameterException、JSONException{
//byte[]plainBytes=“testString”.getBytes();
//json编码
JSONObject obj=新的JSONObject();
obj.put(“电子邮件”、“用户名”);
obj.put(“密码”、“密码”);
对象放置(“操作”、“登录”);
byte[]plainBytes=obj.toString().getBytes();
字符串hashedKey=hashedData(“thisismysecretkey”);
//使用KeyGenerator生成新密钥
/*KeyGenerator rc4KeyGenerator=KeyGenerator.getInsta