首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >android中的RSA /非对称解密

android中的RSA /非对称解密
EN

Stack Overflow用户
提问于 2018-08-03 23:41:54
回答 1查看 229关注 0票数 0

编辑:根据注释重构代码,按照建议的验证Base64

我正在尝试解码一个RSA加密串在Android上,但没有成功。

代码语言:javascript
复制
// 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命令

代码语言:javascript
复制
openssl rsautl -encrypt -pubin -inkey rsakey.pub -in key.txt | base64 -w 0 > enc_base64.txt

我已经通过在源代码中使用私钥来解密有效负载,如下所示。

代码语言:javascript
复制
cat key.base64 | base64 --decode |  openssl rsautl -decrypt -inkey rsakey.key

上面显示的代码运行良好,没有异常,但解密的有效负载无效。

下面是Logcat的摘录

代码语言:javascript
复制
// 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-04 08:32:02

这里有一些缺失的细节,但有一个bug会立即跳出来:

代码语言:javascript
复制
Cipher cipher = Cipher.getInstance(clientKey.getAlgorithm());

Key.getAlgorithm()返回的信息不足以用作Cipher.getInstance()的参数。它可能返回而不抛出异常,但结果将不正确。相反,始终将完整的转换字符串“算法/模式/填充”指定为Cipher.getInstance()的参数。如果您真的像您在openssl中指出的那样对数据进行了加密,那么这一行应该是正确的:

代码语言:javascript
复制
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51676070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档