【问题标题】:Decryption using private key issue in Android在Android中使用私钥问题解密
【发布时间】:2016-12-08 02:50:42
【问题描述】:

我从后端服务器获取了一个加密字符串,我需要在 Android 中使用私钥对其进行解密。解密有效,但它在解密字符串的末尾附加了一个特殊字符。 这是我正在使用的代码:

public static String decryptString(String value, Context context){

    value = "Ss7LVqgWeamgPGkt62qSNydTJnwiUet8UemYWR0jzCLOvtW+RazpJmGG657/nWhu5UQGXzEMwIK1jcBXIXkw3EAX6WdocYBKpVJPWpmlEbf4IzPcev67wgx4vd3ylK8KrpPDj92EKE6ElDi/U91e+VS3bhURHye0w9ncaITTm+szGFiDL/fcy+0hnrYJdA3IrElZntYk14SCccb2M0LJ+nTFdfzEgsUH8vW5ei986d4HTKUqBvkoU+JAtHXTYq1sKNSd4L3Xm5fZ0OPpdIKEWqHDntjsMRsX62eTON+iC1OVsKK2vRqvSbVLvE45ww3N6iZNBG1gewcC8v5wJwonmA==";
    byte[] decodedBytes = null;
    try {
        //Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding", "AndroidOpenSSL");
        //Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "AndroidOpenSSL");
        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
        c.init(Cipher.DECRYPT_MODE,  getPrivateKey(context) );

        decodedBytes = c.doFinal(Base64.decode(value, Base64.DEFAULT));


        //decodedBytes = c.doFinal(value.getBytes("ISO-8859-1"));

    } catch (Exception e) {
        e.printStackTrace();
    }

    return new String(decodedBytes);
}  

public static PrivateKey getPrivateKey(Context context){

    // reads the key_public key stored in a file
    InputStream is = context.getResources().openRawResource(R.raw.key_private);

    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    List<String> lines = new ArrayList<String>();
    String line = null;

    try {


        while ((line = br.readLine()) != null)
            lines.add(line);


        // removes the first and last lines of the file (comments)
        if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size()-1).startsWith("-----")) {
           lines.remove(0);
         lines.remove(lines.size()-1);
        }

        // concats the remaining lines to a single String
        StringBuilder sb = new StringBuilder();
        for (String aLine: lines)
            sb.append(aLine);
        String keyString = sb.toString();
        byte [] encoded = Base64.decode(keyString, Base64.DEFAULT);



    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        PrivateKey myPrivKey = keyFactory.generatePrivate(keySpec);

        return myPrivKey;

    }catch (Exception e){

        e.printStackTrace();
    }
    return null;

}

最后,我从主活动中调用第一个函数:

String decryptedString =  AppUtils.decryptString(encryptedString, MainActivity.this);

我附上我的私钥以供参考:

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDuDOP1sBXEKUwR
WQcH459iGj74fGPqnIFJ+cOxNFFeymXs0L0u4n7v6NCAGvZJ5HtdWeUbT+xMMNMW
k8swrQs/qZ36KXzxhL6hy0gj4i86G5L73vQ39g/qlnxhfR+OxhVnDUE4TOt9xhN9
20Mf6xVhVOVmUQwhny6sQqvkhaebzJ32QuTlHFVT8mMGSTwXcHUqRi2ApeyRW9ln
BCLf/P5k+/O5W4lRmyfvumZoipegf0e75hGmgJYxXETomU50DmLMNdQ05/rlpcW5
FEm3Gf60pd+/mqkB+3LlyTPAM7sEfwKgL+CZSqYtz3O/m7tYSK7BtCIbE1bvksjj
bPQA1DYXAgMBAAECggEAZDvDRLEnCRjGccuFvVmnw7v/ZcuimqfZfJeRQa0g0gPx
FNzzu6kc/9GM8VPo/kYZd74hTPXDLnWkfC4w8Ub7pIu7/Bi6Bkv5pNCeiJV1g0cX
BbzkIigWnZVNvBLeVdSsMF8RZi5lPelITcckJW1r7Da9/O4FaKbJFTlhfXCVmXCn
74Bs0q8QZHA/WLwcy5DP+uqdko8T3vtBSPx7HEBbEhy94SEAsQfkdLTa0KQ2WlLI
ythR5DH0GUIoTIBeFsM7w2Ldj7EYbviC8OlIu3h3wHwPutAVzweqsSq5OPAwPnNP
oQZz6gqNaldE0jwVDD8aoLOzCrw1+NW0AmzWJx1VgQKBgQD5g1m8PagCwb/2BQqi
Q3ORjmbHS9dIo3IV+2RM7bYag5fv5CEfApH42rGzPr/pebmYIVQnfYkqDrfHmR95
56+7bOXxKDTkSCdursRa23L3WbIokhLJOPVr7FARc+mKFUEkrpHZcDsIoIUw+Bn4
Sa2myhFvazuJoGpjjAk8olpc1wKBgQD0PT+/ahG5tWW9Nt7wvQfi+KWW5l0fWb+R
ozbuFnZbmKkQZ45bCdU/G3qImtdtTynGX4LjaSyh/vEtebLlrCsfzRc7hQRHpM3o
9tjPUX8zSFNQQA8I7+iTQRQtdiAeOeEt5kethWG9qSbnkBFzkXwVhdvdkhRy4EzW
aKVwU26IwQKBgQCa4oiPq45ht7fbliGVvF0/G7B9QnzvIFavgpAumNkT+GAWj/xn
bYcDfW4VoHwtCFzHLNk6clj0/JHkmw7I86NIqz7JxnWex5OCx4YoCFWDafCH8rUq
p+rhBZ5mVxe/mZYImTz8Rwi+QDatwTUNxV7ATGsqSNx6gFPKW6FYPEfvnQKBgEvd
fqCxjOH3k6urkKKMxRdejukJk2F6mkPdw+E+vvMCv3kmAZULv96DZZNrLYF5tos0
/c4vzDphm365r7Uhvp95MD8/uS2b5o33py72rKE8VQy3aTQoeUDMVT0t1RoudmCw
iBFBPjQQh9Ij8RfJ2BZDZyEzEAEC5TswdDso30vBAoGBAJQqlK6mjhyCmqAs8V2j
vHbzv2/NTG2sYOaMGMsk1Zeh5nQq98rHA/7s1eEkX4AlC38QXisvKi7ywYrlpZoz
+K0Z1sd0tlysH74cK8xWDnLQ4j9l0rD9RtxYHlrdldrsP4P4rE1a2SwAchM3GDpG
R3LcU9BOe9ch+aW3b+PRIkgK
-----END PRIVATE KEY-----

这是输出:

NDcxMDQ3MjguMTQ2ODg3NTI4MTr4iAAldbBVX2RD3cNw/rlKpmOp1p8YXIYqUVlvX7rmgg==��

解密后的字符串应该以“==”结尾。有人可以帮我弄清楚,如何删除解密后字符串末尾的特殊字符。

谢谢

【问题讨论】:

  • 哪些字符是特殊字符?
  • 解密字符串末尾的最后2个问号
  • 我知道,但是特殊字符是什么?它们有 ASCII 值吗?
  • 更重要的是,十六进制的最后两个字符的值是什么,因为它们似乎不是 ASCII 可打印字符。?
  • 这是字节码数组作为十六进制字符串:4E4463784D4451334D6A67754D5451324F4467334E5449344D5472346941416C646242565832524433634E772F726C4B706D4F70317038595849597155566C765837726D67673D3D00其中最后2个字符为00 跨度>

标签: android encryption rsa private-key


【解决方案1】:

这些末尾的值必须是在加密期间添加的。它们可能是00 值字节,由具有空终止字符串或类似字符串的语言添加。关键是,如果密文本身被改变,PKCS#1 unpadding 会失败,所以唯一合理的解释是明文中已经包含了值。

以十六进制打印出decodedBytes 以找出值。您可能可以使用String#trim() 方法摆脱它们。

【讨论】:

  • 并注意,base 64 被加密而不是所表示的字节数组这一事实应该已经表明创建加密方法的人没有线索......跨度>
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 2017-07-07
  • 1970-01-01
  • 2022-10-20
  • 2020-02-28
  • 1970-01-01
相关资源
最近更新 更多