关于Android公钥的澄清?

时间:2012-08-27 20:54:19

标签: android string encryption google-play in-app-billing

我对来自http://developer.android.com/guide/google/play/billing/billing_integrate.html#billing-signatures

的一些建议感到困惑
  

要保护您的公钥免受恶意用户和黑客的攻击,请不要这样做   将您的公钥嵌入为整个文字字符串。相反,构建   运行时从字符串或使用位操作的字符串(for   例如,XOR与其他一些字符串)来隐藏实际的密钥。钥匙   本身并不是秘密信息,但你不想让它变得简单   黑客或恶意用户用另一个公钥替换公钥   键。

这是否意味着

String one = "thisIs";
String two = "MyKey";
String base64EncodedPublicKey = one + two;
PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
verified = Security.verify(key, signedData, signature);

更安全
String base64EncodedPublicKey = "thisIsMyKey";
PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
verified = Security.verify(key, signedData, signature);

?如果没有,你能否在代码中给我一个如何做到这一点的例子?

2 个答案:

答案 0 :(得分:4)

涉及密钥更改的事情最好。就个人而言,我更喜欢使用加密,这样的东西会起作用。对于密钥,将几个部分串在一起,它应该有助于将它们组合在一起。使用encryptKey加密密钥,然后从源代码中删除真实密钥,您应该相当安全。更好的方法是以某种方式从安全的服务器获取密钥,但这并不总是一种选择。

String encryptKey(String input)
{
    byte[] inBytes=input.getBytes();
    String finalString=null;
    try {
        Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] keyBytes=md.digest((KeyPart1+KeyPart2).getBytes());
        keyBytes = Arrays.copyOf(keyBytes, 16);
        SecretKey key= new SecretKeySpec(keyBytes,"AES");
        IvParameterSpec ivSpec = new IvParameterSpec(new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
        cipher.init(Cipher.ENCRYPT_MODE,key,ivSpec);
        byte[] outBytes = new byte[cipher.getOutputSize(inBytes.length)];
        //cipher.update(encrypted, 0, encrypted.length, decrypted, 0);
        outBytes=cipher.doFinal(inBytes);
        finalString=new String(Base64.encode(outBytes,0));
        Log.v(TAG,"Encrypted="+finalString);

    } catch (NoSuchAlgorithmException e) {
        Log.e(TAG,"No Such Algorithm",e);
    } catch (NoSuchPaddingException e) {
        Log.e(TAG,"No Such Padding",e);
    } catch (InvalidKeyException e) {
        Log.e(TAG,"Invalid Key",e);
    } catch (InvalidAlgorithmParameterException e) {
        Log.e(TAG,"Invalid Algorithm Parameter",e);
    } catch (IllegalBlockSizeException e) {
    } catch (BadPaddingException e) {}
    return finalString;
}

String decryptKey(String base64Text)
{
    byte[] encrypted=Base64.decode(base64Text,0);
    //encrypted=base64Text.getBytes();
    String decryptedString=null;
    try {
        Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] keyBytes=md.digest((KeyPart1+KeyPart2).getBytes());
        keyBytes = Arrays.copyOf(keyBytes, 16);
        SecretKey key= new SecretKeySpec(keyBytes,"AES");
        IvParameterSpec ivSpec = new IvParameterSpec(new byte[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
        cipher.init(Cipher.DECRYPT_MODE,key,ivSpec);
        byte[] decrypted = new byte[cipher.getOutputSize(encrypted.length)];
        //cipher.update(encrypted, 0, encrypted.length, decrypted, 0);
        decrypted=cipher.doFinal(encrypted);
        decryptedString=new String(decrypted);
    } catch (NoSuchAlgorithmException e) {
        logStackTrace(e);
    } catch (NoSuchPaddingException e) {
        logStackTrace(e);
    } catch (InvalidKeyException e) {
        logStackTrace(e);
    } catch (InvalidAlgorithmParameterException e) {
        logStackTrace(e);
    } catch (IllegalBlockSizeException e) {
        logStackTrace(e);
    } catch (BadPaddingException e) {
        logStackTrace(e);
    }
    return decryptedString;
}

答案 1 :(得分:3)

是。虽然在这种情况下你只是连接不太好的字符串。这样做的原因是有人可以轻松地反汇编代码并访问您的公钥。如果你必须重新组装密钥,那么从反汇编代码中获取密钥会更具挑战性。