8

我对来自http://developer.android.com/guide/google/play/billing/billing_integrate.html#billing-signatures的这条建议感到困惑

为了保护您的公钥免受恶意用户和黑客的攻击,请勿将您的公钥嵌入为整个文字字符串。相反,在运行时从片段构造字符串或使用位操作(例如,与其他字符串进行异或)来隐藏实际密钥。密钥本身不是秘密信息,但您不想让黑客或恶意用户轻易地用另一个密钥替换公钥。

这是否意味着

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);

? 如果没有,您能否给我一个如何执行此操作的代码示例?

4

2 回答 2

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;
}
于 2013-12-11T02:48:22.327 回答
3

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

于 2012-08-27T21:09:45.557 回答