编辑:基于注释重构代码,以根据建议验证Base64
我尝试在Android上解码RSA加密字符串,但未成功。
// Retrieve the key from server
// Looks counter intuitive, but, the retrieval happens on trusted Intranet.
URL keyUrl = new URL(keyUri);
URLConnection keyConn = keyUrl.openConnection();
InputStream keyStream = keyConn.getInputStream();
// Create the keystore and load the key
KeyStore pkcsStore = KeyStore.getInstance("PKCS12");
pkcsStore.load(keyStream, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(pkcsStore, "password".toCharArray());
// Retrieve the key from keystore
String clientKeyAlias = pkcsStore.aliases().nextElement();
Key clientKey = pkcsStore.getKey(clientKeyAlias, "password".toCharArray());
Log.d(TAG, String.format("Algorithm: %s Format: %s ", clientKey.getAlgorithm(), clientKey.getFormat()));
// Retrieve the public key from keystore
Certificate certificate = pkcsStore.getCertificate(clientKeyAlias);
PublicKey clientPublicKey = certificate.getPublicKey();
// Let's make sure the certificate/key stored in pkcsStore are valid
String plainText = "Stackoverflow is Amazing!";
Log.d(TAG, String.format("Encrypting string '%s' to validate cert/key pair stored in pkcs store", plainText));
byte[] plainTextBytes = plainText.getBytes("UTF-8");
// Let's get the cipher instance
Cipher testCipher = Cipher.getInstance(clientKey.getAlgorithm());
testCipher.init(Cipher.ENCRYPT_MODE, clientPublicKey);
byte[] encryptedTextBytes = testCipher.doFinal(plainTextBytes);
testCipher.init(Cipher.DECRYPT_MODE, clientKey);
byte[] decryptedTextBytes = testCipher.doFinal(encryptedTextBytes);
String decryptedPlainText = new String(decryptedTextBytes, "UTF-8");
Log.d(TAG, "Decrypted plainText " + decryptedPlainText);
// Retrieve the encrypted data from server
URL symUrl = new URL(symUri);
URLConnection connection = symUrl.openConnection();
int contentLength = connection.getContentLength();
Log.d(TAG, "Content length " + contentLength);
InputStream is = connection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// Validate the base64 string matches the data on server
String payLoad = br.readLine().trim(); // Trim the line in case echo there is a newline character
String base64StringOnServer = "nMdLvh+PDH1DimjQV0kTYU9E5tJA9VA2ADlcCQVkYwYZQWRFdT57bW4oDvlpGJ1KzJ/N3smyV5N7xlpNJo6HXans+cCImZI5MaZ9prEc3gUtIlwDWj80e0L+5YaRSIshXjPKvurjhwmppz+IAuh5Aq/c3ZdE2nbFn+L+2Ih91nsl6WV1diCEBw6pUIMtdPh8nXmQfp3ZbDKHt3VnSkoLLhPXYbYaTOaTuhAJZhszE5ejpB0sQ78d/1WbmPU1MnGCrUSOkM6s22fT3aTyzxo3IjmzXBWhz32tCbOBagmAsyaHlLHbQ2pQoxI9cR0hcZAc/IyEFKrVSJnFA03P/QzkhQ==";
Log.d(TAG, "Base64 as stored on the server: " + base64StringOnServer);
Log.d(TAG, "Base64 received from server: " + payLoad);
if (base64StringOnServer.equals(payLoad)) {
Log.d(TAG, "Base64 string comparision passed");
}
// Get the byte array of payload
byte[] data = Base64.decode(payLoad, Base64.DEFAULT);
// Decipher the data
Cipher cipher = Cipher.getInstance(clientKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, clientKey);
byte[] decryptedKeyBytes = cipher.doFinal(data);
// Validate the decrypted data
String decryptedKey = new String (decryptedKeyBytes, "UTF-8");
Log.d(TAG, "Decrypted Key: " + decryptedKey);
这是openssl命令对数据进行加密
openssl rsautl -encrypt -pubin -inkey rsakey.pub -in key.txt | base64 -w 0 > enc_base64.txt
我已经通过在源处使用私钥对有效载荷进行了解密,如下所示。
cat key.base64 | base64 --decode | openssl rsautl -decrypt -inkey rsakey.key
上面显示的代码运行正常,没有异常,但是解密的有效载荷无效。
这是Logcat的摘录
// Base64 decode flag Base64.NO_WRAP
Algorithm: RSA Format: PKCS#8
Encrypting string 'Stackoverflow is Amazing!' to validate cert/key pair stored in pkcs store
Decrypted plainText Stackoverflow is Amazing!
Content length 344
Base64 as stored on the server: nMdLvh+PDH1DimjQV0kTYU9E5tJA9VA2ADlcCQVkYwYZQWRFdT57bW4oDvlpGJ1KzJ/N3smyV5N7xlpNJo6HXans+cCImZI5MaZ9prEc3gUtIlwDWj80e0L+5YaRSIshXjPKvurjhwmppz+IAuh5Aq/c3ZdE2nbFn+L+2Ih91nsl6WV1diCEBw6pUIMtdPh8nXmQfp3ZbDKHt3VnSkoLLhPXYbYaTOaTuhAJZhszE5ejpB0sQ78d/1WbmPU1MnGCrUSOkM6s22fT3aTyzxo3IjmzXBWhz32tCbOBagmAsyaHlLHbQ2pQoxI9cR0hcZAc/IyEFKrVSJnFA03P/QzkhQ==
Base64 received from server: nMdLvh+PDH1DimjQV0kTYU9E5tJA9VA2ADlcCQVkYwYZQWRFdT57bW4oDvlpGJ1KzJ/N3smyV5N7xlpNJo6HXans+cCImZI5MaZ9prEc3gUtIlwDWj80e0L+5YaRSIshXjPKvurjhwmppz+IAuh5Aq/c3ZdE2nbFn+L+2Ih91nsl6WV1diCEBw6pUIMtdPh8nXmQfp3ZbDKHt3VnSkoLLhPXYbYaTOaTuhAJZhszE5ejpB0sQ78d/1WbmPU1MnGCrUSOkM6s22fT3aTyzxo3IjmzXBWhz32tCbOBagmAsyaHlLHbQ2pQoxI9cR0hcZAc/IyEFKrVSJnFA03P/QzkhQ==
Base64 string comparision passed
Decrypted Key: )|~`!��u�� zU.�縉)���#9�]���Q�����Ő�A�f*(A�%U�/;�%2��j0I$dI*,'@�E�t@�P�=-C��VR�o06p�4op9�k�q >�qq�>V�~Y���R�O���t2�S�֖E���&�rP�Q��L����2�;7��}�g�Wpٟ$P�N0�k�w��ň1����0�2��2�jҗ/�}r:*g"ոm���[����1234567812345678
// Base64 decode flag Base64.DEFAULT
Algorithm: RSA Format: PKCS#8
Encrypting string 'Stackoverflow is Amazing!' to validate cert/key pair stored in pkcs store
Decrypted plainText Stackoverflow is Amazing!
Content length 344
Base64 as stored on the server: nMdLvh+PDH1DimjQV0kTYU9E5tJA9VA2ADlcCQVkYwYZQWRFdT57bW4oDvlpGJ1KzJ/N3smyV5N7xlpNJo6HXans+cCImZI5MaZ9prEc3gUtIlwDWj80e0L+5YaRSIshXjPKvurjhwmppz+IAuh5Aq/c3ZdE2nbFn+L+2Ih91nsl6WV1diCEBw6pUIMtdPh8nXmQfp3ZbDKHt3VnSkoLLhPXYbYaTOaTuhAJZhszE5ejpB0sQ78d/1WbmPU1MnGCrUSOkM6s22fT3aTyzxo3IjmzXBWhz32tCbOBagmAsyaHlLHbQ2pQoxI9cR0hcZAc/IyEFKrVSJnFA03P/QzkhQ==
Base64 received from server: nMdLvh+PDH1DimjQV0kTYU9E5tJA9VA2ADlcCQVkYwYZQWRFdT57bW4oDvlpGJ1KzJ/N3smyV5N7xlpNJo6HXans+cCImZI5MaZ9prEc3gUtIlwDWj80e0L+5YaRSIshXjPKvurjhwmppz+IAuh5Aq/c3ZdE2nbFn+L+2Ih91nsl6WV1diCEBw6pUIMtdPh8nXmQfp3ZbDKHt3VnSkoLLhPXYbYaTOaTuhAJZhszE5ejpB0sQ78d/1WbmPU1MnGCrUSOkM6s22fT3aTyzxo3IjmzXBWhz32tCbOBagmAsyaHlLHbQ2pQoxI9cR0hcZAc/IyEFKrVSJnFA03P/QzkhQ==
Base64 string comparision passed
Decrypted Key: )|~`!��u�� zU.�縉)���#9�]���Q�����Ő�A�f*(A�%U�/;�%2��j0I$dI*,'@�E�t@�P�=-C��VR�o06p�4op9�k�q >�qq�>V�~Y���R�O���t2�S�֖E���&�rP�Q��L����2�;7��}�g�Wpٟ$P�N0�k�w��ň1����0�2��2�jҗ/�}r:*g"ոm���[����1234567812345678
答案 0 :(得分:2)
有一些遗漏的细节,但立即跳出的一个错误是:
Stream
Cipher cipher = Cipher.getInstance(clientKey.getAlgorithm());
返回的信息不足,无法用作Key.getAlgorithm()
的参数。它可能会返回而不会引发异常,但是结果将不正确。相反,请始终将完整的转换字符串“ algorithm / mode / padding ”指定为Cipher.getInstance()
的参数。如果您确实按照Cipher.getInstance()
的指示对数据进行了加密,那么这将是正确的行:
openssl