Java:使用 java.util.Base64 与 android.util.Base64 解码 base64 字符串时的不同结果

Posted

技术标签:

【中文标题】Java:使用 java.util.Base64 与 android.util.Base64 解码 base64 字符串时的不同结果【英文标题】:Java: Different results when decoding base64 string with java.util.Base64 vs android.util.Base64 【发布时间】:2015-10-04 16:35:30 【问题描述】:

我正在开发客户端/服务器系统,并且正在尝试进行一些基本的加密。当我连接到服务器时,我通过套接字发送一个公钥作为转义字符串。我已经验证了字符串在两端、换行符和所有方面都是 相同 的。

在客户端 (android) 上,我可以使用公钥/私钥成功加密和解密密钥(用于测试目的)。但是,当尝试将公钥从 String 解码为 byte[] 时,服务器直接失败了:

 java.lang.IllegalArgumentException: Illegal base64 character a

这似乎很荒谬,因为“a”绝对是一个 base64 字符,如果我理解正确的话。客户端和服务器使用共享库来处理所有加密,因此代码几乎相同。 唯一的区别在于编码/解码 base64 字符串,因为 java.util.Base64 在 Android 上不可用。

共享课程

public abstract class EasyCrypt 

...

    public PublicKey loadPublicKey(String key64) throws GeneralSecurityException 

        byte[] data = decode(key64); //Calls abstract methods, shown below

        X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        return fact.generatePublic(spec);
    

...


客户端 (Android) 方法

import android.util.Base64;

public class ClientCrypt extends EasyCrypt 
    @Override
    protected byte[] decode(String s) 
        return Base64.decode(s.getBytes(), Base64.DEFAULT); //Works perfectly
    

    @Override
    protected String encode(byte[] bytes) 
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    

服务器 (Linux) 方法

import java.util.Base64;

public class ServerCrypt extends EasyCrypt
    @Override
    public byte[] decode(String str)
        return Base64.getDecoder().decode(str); //Throws IllegalArgumentException
    

    @Override
    public String encode(byte[] bytes)
        return Base64.getEncoder().encodeToString(bytes);
    

【问题讨论】:

尝试在android中使用Base64.NO_WRAP而不是DEFAULT Android 是正常工作的。 你在android上编码吧?如果是,那么在您的 android 上的编码方法中尝试 Base64.NO_WRAP 你能显示你尝试解码的 base64str 吗? 我相信你有格式问题,它以某种方式包装或标签 【参考方案1】:

在安卓上,使用Base64.NO_WRAP 而不是Base64.DEFAULT

@Override
protected String encode(byte[] bytes) 
    return Base64.encodeToString(bytes, Base64.NO_WRAP);

【讨论】:

@Mohammad Adil 我从服务器获得了一个由 java.util.Base64 类编码的字符串,我正在用 android.util.base64 解码该字符串,但没有给出预期的结果。请帮助我 感谢 Base64.NO_WRAP 它在我的 Java 后端工作(使用 java.util.Base64)。 想在java中做。我没有安卓。通过使用 java.util.Base64 结果不同【参考方案2】:

Base64.getMimeDecoder()代替Base64.getDecoder()

【讨论】:

java.util.Base64.getMimeDecoder() 调用需要 API 级别 26。 检查this link以获得进一步的解释。

以上是关于Java:使用 java.util.Base64 与 android.util.Base64 解码 base64 字符串时的不同结果的主要内容,如果未能解决你的问题,请参考以下文章

java新版本Base64Encoder和Base64Decoder无法使用解决方案

java新版本Base64Encoder和Base64Decoder无法使用解决方案

为什么java.util.Base64和org.apache.commons.ssl.Base64彼此不兼容?

从文件中读取数据并编码成base64 java

java.util.Base64解码然后编码产生不同的字符串

Base64