java、android和Objective的通用加密
我想使用Java、Android和Objective-C通用的加密和解密算法。我在Java和Android中尝试了AES,两者都返回不同的输出。Java、Android和Objective-C是否有通用算法 下面是java代码java、android和Objective的通用加密,java,android,objective-c,Java,Android,Objective C,我想使用Java、Android和Objective-C通用的加密和解密算法。我在Java和Android中尝试了AES,两者都返回不同的输出。Java、Android和Objective-C是否有通用算法 下面是java代码 import java.security.*; import java.security.spec.InvalidKeySpecException; import javax.crypto.*; import javax.crypto.spec.SecretKeySpe
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.*;
public class AESencrp {
private static final String ALGO = "AES";
private static final byte[] keyValue =
new byte[] { 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, ALGO);
return key;
}
public static void main(String[] args) throws Exception {
// String password = "1";
// String passwordEnc = AESencrp.encrypt(password);
String passwordDec = AESencrp.decrypt("1");
// System.out.println("Plain Text : " + password);
// System.out.println("Encrypted Text : " + passwordEnc);
System.out.println("Decrypted Text : " + passwordDec);
}
}
这是我的Android代码
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
public class EncodeDecodeAES {
private final static String HEX = "0123456789ABCDEF";
private final static int JELLY_BEAN_4_2 = 17;
private final static byte[] key = { 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };
// static {
// Security.addProvider(new BouncyCastleProvider());
// }
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
String fromHex = toHex(result);
String base64 = new String(Base64.encodeToString(fromHex.getBytes(), 0));
return base64;
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] seedByte = seed.getBytes();
System.arraycopy(seedByte, 0, key, 0, ((seedByte.length < 16) ? seedByte.length : 16));
String base64 = new String(Base64.decode(encrypted, 0));
byte[] rawKey = getRawKey(seedByte);
byte[] enc = toByte(base64);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
public static byte[] encryptBytes(String seed, byte[] cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext);
return result;
}
public static byte[] decryptBytes(String seed, byte[] encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = decrypt(rawKey, encrypted);
return result;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES"); // , "SC");
SecureRandom sr = null;
if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
try {
kgen.init(256, sr);
// kgen.init(128, sr);
} catch (Exception e) {
// Log.w(LOG, "This device doesn't suppor 256bits, trying 192bits.");
try {
kgen.init(192, sr);
} catch (Exception e1) {
// Log.w(LOG, "This device doesn't suppor 192bits, trying 128bits.");
kgen.init(128, sr);
}
}
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES"); // /ECB/PKCS7Padding", "SC");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES"); // /ECB/PKCS7Padding", "SC");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
}
导入java.security.SecureRandom;
导入javax.crypto.Cipher;
导入javax.crypto.KeyGenerator;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.SecretKeySpec;
导入android.util.Base64;
公共类编码{
私有最终静态字符串HEX=“0123456789ABCDEF”;
私人最终静态整数果冻豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆豆=17;
私有最终静态字节[]键={W',e',l',c',o',m',e',t',o',e',n',c',r',y',p',t'};
//静止的{
//addProvider(新的BouncyCastleProvider());
// }
公共静态字符串加密(字符串种子、字符串明文)引发异常{
byte[]rawKey=getRawKey(seed.getBytes());
byte[]result=encrypt(rawKey,cleartext.getBytes());
字符串fromHex=toHex(结果);
String base64=新字符串(base64.encodeToString(fromHex.getBytes(),0));
返回base64;
}
公共静态字符串解密(字符串种子、字符串加密)引发异常{
byte[]seedByte=seed.getBytes();
数组复制(seedByte,0,key,0,((seedByte.length<16)?seedByte.length:16));
String base64=新字符串(base64.decode(加密,0));
byte[]rawKey=getRawKey(seedByte);
字节[]enc=toByte(base64);
字节[]结果=解密(rawKey,enc);
返回新字符串(结果);
}
公共静态字节[]encryptBytes(字符串种子,字节[]明文)引发异常{
byte[]rawKey=getRawKey(seed.getBytes());
字节[]结果=加密(rawKey,明文);
返回结果;
}
公共静态字节[]解密字节(字符串种子,字节[]加密)引发异常{
byte[]rawKey=getRawKey(seed.getBytes());
字节[]结果=解密(rawKey,加密);
返回结果;
}
私有静态字节[]getRawKey(字节[]种子)引发异常{
KeyGenerator kgen=KeyGenerator.getInstance(“AES”);/,“SC”);
SecureRandom sr=null;
if(android.os.Build.VERSION.SDK\u INT>=JELLY\u BEAN\u 4\u 2){
sr=SecureRandom.getInstance(“SHA1PRNG”、“Crypto”);
}否则{
sr=SecureRandom.getInstance(“SHA1PRNG”);
}
高级种子(种子);
试一试{
千克初始值(256,sr);
//kgen.init(128,sr);
}捕获(例外e){
//w(Log,“此设备不支持256位,尝试192位。”);
试一试{
kgen.init(192,sr);
}捕获(异常e1){
//w(Log,“此设备不支持192位,尝试128位。”);
kgen.init(128,sr);
}
}
SecretKey skey=kgen.generateKey();
字节[]原始=skey.getEncoded();
返回原材料;
}
私有静态字节[]加密(字节[]原始,字节[]清除)引发异常{
SecretKeySpec skeySpec=新SecretKeySpec(原始,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);///ECB/PKCS7Padding,“SC”);
cipher.init(cipher.ENCRYPT_模式,skeySpec);
字节[]加密=cipher.doFinal(清除);
返回加密;
}
私有静态字节[]解密(字节[]原始,字节[]加密)引发异常{
SecretKeySpec skeySpec=新SecretKeySpec(原始,“AES”);
Cipher Cipher=Cipher.getInstance(“AES”);///ECB/PKCS7Padding,“SC”);
cipher.init(cipher.DECRYPT_模式,skeySpec);
字节[]解密=cipher.doFinal(加密);
返回解密;
}
公共静态字符串toHex(字符串txt){
返回到hex(txt.getBytes());
}
公共静态字符串fromHex(字符串十六进制){
返回新字符串(toByte(hex));
}
公共静态字节[]toByte(字符串hexString){
int len=hexString.length()/2;
字节[]结果=新字节[len];
对于(int i=0;i>4)和0x0f)).append(十六进制字符(b和0x0f));
}
}
我在Android中使用了相同的Java代码,而不是Base64编码器,我使用Base64,它工作得非常好
private static byte[] keyValue = new byte[]{ 'W', 'e', 'l', 'c', 'o', 'm', 'e','t', 'o', 'e', 'n','c', 'r', 'y', 'p', 't' };
private String seedWith16Chars = new String(keyValue);
private String textToEncrypt = "1";
private TextView seed;
private TextView text;
private TextView encryptedValue;
private TextView decryptedValue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seed = (TextView) findViewById(R.id.seedName);
seed.setText(seedWith16Chars);
text = (TextView) findViewById(R.id.textToEncrypt);
text.setText(textToEncrypt);
encryptedValue = (TextView) findViewById(R.id.encryptedText);
decryptedValue = (TextView) findViewById(R.id.decryptedText);
try {
// This value was got when did run it from an 2.3.3 device a Galaxy SII running Android 4.0.4
String encrypted = "";
// Uncomment the line bellow and comment the line above to run it on an Android 4.1.2 or older.
// String encrypted = EncodeDecodeAES.encrypt(seedWith16Chars, textToEncrypt);
Log.e("Encrypt", encrypted);
encrypted = encrypt(textToEncrypt);//EncodeDecodeAES.encrypt(seedWith16Chars, textToEncrypt);
encryptedValue.setText("Encrypt "+encrypted);
String decrypted = decrypt(encrypted);//EncodeDecodeAES.decrypt(seedWith16Chars, encrypted);
decryptedValue.setText("Decrypt "+decrypted);
Log.e("Decrypt", decrypted);
} catch (Exception e) {
Log.e("Exception", e.getLocalizedMessage());
}
}
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
String encryptedValue = Base64.encodeToString(encVal, 0);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = Base64.decode(encryptedData, 0);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
Key key = new SecretKeySpec(keyValue, "AES");
return key;
}
看起来在android版本中,您有一个额外的步骤。在加密和base64编码之间转换为十六进制。这是不必要的,与纯java版本不同。首先,感谢您的回复。Java使用的BASE64Encoder在android中不受支持。此外,在android版本中,您似乎从未使用过定义的“密钥”,但我仍然认为toHex调用将生成不同的结果。密钥用于decrypt()方法。那么BASE64Endoder是否有其他替代方法。但是在java版本中,您在加密中使用keyValue。因此,您正在使用不同的密钥进行加密。