我使用以下代码来加密和解密Java中的数据。加密和解密工作正常。
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.SecureRandom;
public class MainNew {
public static void main(String[] args) throws Exception{
String iv = getEncryptionIV();
System.out.println(" iv = "+iv);
String encryptedData= encryptWithIVandKey(iv,encryptionKey,"hello world! golang is awesome!");
System.out.println(encryptedData);
String decryptedData = decrypt (iv,encryptionKey,encryptedData);
System.out.println(decryptedData);
}
static final String encryptionKey = "rakesh1@n1111112";
static byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(encryptMode, key, new IvParameterSpec(DatatypeConverter.parseBase64Binary(iv)));
byte[] data = cipher.doFinal(bytes);
return data;
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return null;
}
static SecretKey generateKey(String passphrase) {
SecretKey key = null;
try {
key = new SecretKeySpec(passphrase.getBytes("UTF-8"), "AES");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return key;
}
static String getEncryptionIV() {
SecureRandom random = new SecureRandom();
byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
return DatatypeConverter.printBase64Binary(ivBytes);
}
static String encryptWithIVandKey( String iv, String passphrase, final String strToEncrypt) {
String encryptedStr = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = generateKey(passphrase);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(DatatypeConverter.parseBase64Binary(iv)));
encryptedStr = DatatypeConverter.printBase64Binary(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return encryptedStr;
}
static String decrypt(String iv, String passphrase, String ciphertext) {
try {
SecretKey key = generateKey(passphrase);
byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, DatatypeConverter.parseBase64Binary(ciphertext));
return new String(decrypted, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
return "";
}
}
但是如果我使用https://play.golang.org/p/u4fip_ZW6a代码在golang中解密。解密后的值中缺少前16个字符。
答案 0 :(得分:2)
您在游乐场分享的Go代码:
encryptedStr = DatatypeConverter.printBase64Binary(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
正如您所看到的,此代码期望encryptWithIVandKey
的前16个字节为IV。
但是,在您的Java代码中,您只需:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = generateKey(passphrase);
byte[] ivBytes = DatatypeConverter.parseBase64Binary(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));
byte[] encBytes = cipher.doFinal(strToEncrypt.getBytes("UTF-8"));
// concat iv + encripted bytes
byte[] concat = new byte[ivBytes.length + encBytes.length];
System.arraycopy(ivBytes, 0, concat, 0, ivBytes.length);
System.arraycopy(encBytes, 0, concat, ivBytes.length, encBytes.length);
encryptedStr = DatatypeConverter.printBase64Binary(concat);
所以你加密字符串,然后你要返回的所有内容(然后在Go程序中使用)。
正如我们所看到的,Go代码正在从密文中删除16个字节,这就是您丢失数据的原因。
我建议您更改Java代码,以便在字符串的开头包含IV,以匹配Go代码所期望的内容。
您可以将Java中的adAz5d5J3PAOuxntOe/9uMJgFHwIcdKobhRSKXwspmnxFlSlF40dtBYf9VSY34fU
方法更改为:
var isInput = false;
app.post('/webhook', function (req, res) {
var data = req.body;
if (data.object === 'page') {
data.entry.forEach(function(entry) {
var pageID = entry.id;
var timeOfEvent = entry.time;
entry.messaging.forEach(function(event) {
if (event.message) {
receivedMessage(event);
} else if(event.postback){
receivedPostback(event);
}
else {
console.log("Webhook received unknown event: ", event);
}
});
});
res.sendStatus(200);
}
});
function receivedMessage(event) {
var senderID = event.sender.id;
var recipientID = event.recipient.id;
var timeOfMessage = event.timestamp;
var message = event.message;
console.log("Received message for user %d and page %d at %d with message:",
senderID, recipientID, timeOfMessage);
console.log(JSON.stringify(message));
var messageId = message.mid;
var messageText = message.text;
var messageAttachments = message.attachments;
if (messageText) {
switch (messageText) {
case 'Vote':
delayText(senderID, "Send your message ", 1000);
isInput = true;
break;
default:
if(isInput){
token = messageText;
sendTextMessage(senderID, "token: " + token)
isInput = false;
} else {
sendTextMessage(senderID, "isInput: " + isInput)
}
break;
}
}
}
这里的变化是我们在编码之前将IV +加密的字符串连接到Base64。
然后生成的Base64:
{{1}}
如果你在Go代码中尝试使用String,它将产生你期望的输出。