java - ECC加密解密中的Base64编码/解码

标签 java android encryption cryptography spongycastle

我想测试ECC算法加解密

我将代码写到:

  • 生成 key 对(公钥和私钥)---> 将它们写入文件(可能不安全但我只是测试)。

  • 然后使用公钥加密我的字符串(Java 编写)

  • 现在,我获取加密后的字符串并尝试在 Android 上对其进行解密(使用私钥)

这是我的代码:

  1. 用 Java 加密字符串:

    /// generate key pair
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
    try 
    {
        KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA",BouncyCastleProvider.PROVIDER_NAME);
        g.initialize(spec, new SecureRandom());
        KeyPair keyPair = g.generateKeyPair();
        privateKey = keyPair.getPrivate();
        publicKey = keyPair.getPublic();
        System.out.println("PublicKey:"+publicKey+"\n");
        System.out.println("PrivateKey:"+privateKey+"\n");
    
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
     try {
        Cipher c = Cipher.getInstance("ECIES",BouncyCastleProvider.PROVIDER_NAME);
        c.init(Cipher.ENCRYPT_MODE,publicKey);
        encodeBytes = c.doFinal(origin.getBytes());
        String encrypt = Base64.getEncoder().encodeToString(encodeBytes);
        System.out.println(encrypt);
    } catch (Exception e) {
        e.printStackTrace();
    }
    

我的输出加密字符串是这样的:

BB9Y4sKPbp28y7+FnpGnLGz5aTjD58GiIcXgjnNC4nXlUiqlHVVPc4K+ovlK5HK+Hz1Qps4ZWH9VdoYvm6VE36aEqvy53lJFnANDVpqAKuDUUaqEUrIQgF/TXFCFO22Il411atDsNhvJC3eRXbREL14duQbF8xjnLjru6WLN6GDYAQ==

这是我的私钥

-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgCybVICafKcZiEmGNw+Pj/FfL6GMgDc94/E0zJ/EKgdGgCgYIKoZIzj0DAQehRANCAATRTcV/M0OJE94qlZM7VksMOw35fcuGSxejdgzbyYllWtlIQw9gYhKPZx6t/PVOEOec4DyZq2XwaoNxBxWRboL1
-----END PRIVATE KEY-----
  1. 在 Android 上解密字符串

    encodeBytes = Base64.decode(encrypted_string_above,Base64.DEFAULT);
    try
            {
                KeyFactory factory = KeyFactory.getInstance("ECDSA", "SC");
    
                String state;
                state = Environment.getExternalStorageState();
                File root = Environment.getExternalStorageDirectory();
                File dir = new File(root.getAbsolutePath()+"/disk");
                privateKeyFromFile = generatePrivateKey(factory,dir+"/private.pem");
    
                Cipher c = Cipher.getInstance("ECIES","SC");
                c.init(Cipher.DECRYPT_MODE,privateKeyFromFile);
                decodeBytes = c.doFinal(encodeBytes);
                String deCrypt = new String(decodeBytes,"UTF-8");
    
    
                txtHiden.setText(deCrypt);
                Toast.makeText(activity, deCrypt, Toast.LENGTH_SHORT).show();
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
    

但是我的代码没有成功解密,它有问题:

  10-03 00:52:18.264 28656-28656/com.example.napoleon.luanvana W/System.err: org.spongycastle.jcajce.provider.util.BadBlockException: unable to process block
  10-03 00:52:18.264 28656-28656/com.example.napoleon.luanvana W/System.err:     at org.spongycastle.jcajce.provider.asymmetric.ec.IESCipher.engineDoFinal(IESCipher.java:476)
  10-03 00:52:18.264 28656-28656/com.example.napoleon.luanvana W/System.err:     at javax.crypto.Cipher.doFinal(Cipher.java:2056)
  10-03 00:52:18.264 28656-28656/com.example.napoleon.luanvana W/System.err:     at com.example.napoleon.luanvana.MessageFragment$3.onClick(MessageFragment.java:156)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.view.View.performClick(View.java:6213)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.widget.TextView.performClick(TextView.java:11074)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.view.View$PerformClick.run(View.java:23645)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.os.Looper.loop(Looper.java:154)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6692)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err: Caused by: org.spongycastle.crypto.InvalidCipherTextException: unable to recover ephemeral public key: Sender's public key has invalid point encoding 0x51
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at org.spongycastle.crypto.engines.IESEngine.processBlock(IESEngine.java:409)
  10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at org.spongycastle.jcajce.provider.asymmetric.ec.IESCipher.engineDoFinal(IESCipher.java:472)
 10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     ... 12 more
 10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err: Caused by: java.io.IOException: Sender's public key has invalid point encoding 0x51
 10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at org.spongycastle.crypto.parsers.ECIESPublicKeyParser.readKey(ECIESPublicKeyParser.java:46)
 10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     at org.spongycastle.crypto.engines.IESEngine.processBlock(IESEngine.java:405)
 10-03 00:52:18.265 28656-28656/com.example.napoleon.luanvana W/System.err:     ... 13 more

我认为这可能是由错误的编码/解码字符串 - 字节 - Base64 引起的

(Enctypt side)String encrypt = Base64.getEncoder().encodeToString(encodeBytes);
(Decrypt side): encodeBytes = Base64.decode(encrypted_string_above,Base64.DEFAULT);

但是我对这个问题没有多少经验。

最佳答案

在 ECIE 方案中,您应该使用 ECDH 作为生成加密/解密 key 对的算法,而不是 ECDSA,因为后者是一种数字签名算法。

KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH",BouncyCastleProvider.PROVIDER)

关于java - ECC加密解密中的Base64编码/解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46531114/

相关文章:

java - 我可以将自己的类数据保存到文件中吗?

Java更新序列化文件的数据结构更改

java - 如何将 Javadoc 的输出转换为 MediaWiki 并将其放入 SourceForge 的 wiki?

php - 如何从 AES 加密字符串中添加/删除 PKCS7 填充?

Java Set - 如何根据名称列表进行排序

android - Android 自定义 ListView 中的搜索功能

android - 所有的安卓设备都有不可移动的外部存储吗?

android - 无法在android中将矢量可绘制对象转换为位图可绘制对象

java - 如何隐藏使用 Java 桌面应用程序构建并由 Android 应用程序使用的文件的内容?

javascript - 从对象进行 AES-CCM 解密的 Node 解密