如何安全地将数据从安卓手机发送到安卓电视?

问题描述

我有这个 Android 移动应用程序,它是 NVR 软件的客户端。它使用基本身份验证和 api 密钥进行服务器身份验证。我现在正在为 android 电视构建一个应用程序。我正在添加一个允许使用移动设备进行身份验证的功能。为此,我使用了 Google 的 Nearby 库,其中电视成为广告商,手机成为发现者。我可以毫无问题地将数据(凭据)从手机发送到电视。但是,我想保护数据。我想过使用加密来保护数据,并阅读了 thisthis,但遇到了“javax.crypto.AEADBadTagException:数据太短”或“javax.crypto.BadPaddingException:pad 块损坏”等问题。我认为问题是因为我使用了一个短字符串(6 个字符)作为密钥。

我正在做的是让电视生成一个随机的 6 位代码并将其显示在屏幕上。现在在移动应用程序上,我要求用户输入 6 位代码。然后我使用此代码来加密凭据。当电视接收到数据时,我需要使用相同的数字代码对其进行解密。

这是我的加密和解密代码。目前无法使用。

public class DoCrypto {

    private static final String ENCRYPT_ALGO = "AES/GCM/nopadding";
    private static final int TAG_LENGTH_BIT = 128;
    private static final int IV_LENGTH_BYTE = 12;
    private static final int AES_KEY_BIT = 256;

    private static final Charset UTF_8 = StandardCharsets.UTF_8;

    public static String encrypt(String clearText,String code) throws Exception {

        KeySpec keySpec = new PBEKeySpec(code.tochararray(),code.getBytes(UTF_8),1000,256);
        SecretKey secretKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(keySpec);
        return new String(encrypt(clearText.getBytes(),secretKey));

    }

    public static String decrypt(String encryptedText,256);
        SecretKey secretKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(keySpec);
        return decrypt(encryptedText.getBytes(),secretKey);
    }

    public static byte[] encrypt(byte[] pText,SecretKey secret) throws Exception {

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
        cipher.init(Cipher.ENCRYPT_MODE,secret);
        byte[] encryptedText = cipher.doFinal(pText);
        return encryptedText;

    }

    public static String decrypt(byte[] cText,SecretKey secret) throws Exception {

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
        cipher.init(Cipher.DECRYPT_MODE,secret);
        byte[] plainText = cipher.doFinal(cText);
        return new String(plainText,UTF_8);

    }

}

我正在测试这个

    try {
        String code = DoCrypto.encrypt("Clear Text","1234");
        Log.d("crypt",code);
        Log.d("crypt",DoCrypto.decrypt(code,"1234"));
    } catch (Exception e) {
        e.printstacktrace();
    }

这段代码给了我上面提到的错误“javax.crypto.AEADBadTagException: data too short”。所以也许我在想我可能没有正确地做这件事,因为我只使用了一个 4-6 位的密钥。

是否有更好的方法来保护数据?

更新 #1:

经过一些修补后,我现在收到错误“javax.crypto.AEADBadTagException:GCM 中的 mac 检查失败”。目前正在谷歌搜索以了解原因。

解决方法

Nearby Connections 为两台设备提供一个身份验证令牌 (https://developers.google.com/android/reference/com/google/android/gms/nearby/connection/ConnectionInfo#getAuthenticationToken())。只要您在发送敏感数据前确认,实际连接和数据传输将是安全的。

大多数客户端只是在两个屏幕上显示令牌并有一个确认步骤。有些人将它散列(成一个数字,或成一系列图像),使其更易于阅读。