跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 安卓上一个奇怪的 rsa,每次加密结果都一样
未分類
2020 年 6 月 1 日

安卓上一个奇怪的 rsa,每次加密结果都一样

安卓上一个奇怪的 rsa,每次加密结果都一样

資深大佬 : szvone 59

排版乱了,请看一

大佬有話說 (38)

  • 主 資深大佬 : szvone

    有这么一个函数:

    public static String a(String str, String str2) throws Exception {
    Cipher v1 = Cipher.getInstance(“RSA”);
    v1.init(1, KeyFactory.getInstance(“RSA”).generatePublic(new X509EncodedKeySpec(Base64.decode(str2,Base64.DEFAULT))));
    return Base64.encodeToString(v1.doFinal(str.getBytes()),Base64.DEFAULT);
    }

    用下面的代码调用:

    String key = “MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI6Nnwc6Doyk6sFvN/oVbsjS+EhV661qfVrgfJ/PTNevn” +
    “uDjQQvI8pjooKreTab2sbSUuv2otPxfLC+IyN58ye7UCAwEAAQ==”;

    String res = null;

    try {

    res = a(“13888888888”,key);

    } catch (Exception e) {

    e.printStackTrace();

    }

    得到的 res 始终会是:LTaf1+LNtbI0NHMISTHuiY10rYKQK0BhqkgHqcrM1N8nYWZXUR0WuKMvU4ZzCZD1D0hdO9ZhcXuM1NdL0mOSyg==

    且这个 res 永远都是这个值,RSA 加密的话不是每次都会变动吗,为啥这个就不会变动呢?

    这个用 javascript 怎么实现呢?

  • 資深大佬 : momocraft

    为什么你会期待变动啊

  • 資深大佬 : CEBBCAT

    可能是你选的版本的事儿。发代码可以用 gist

    麻烦您发帖前不要忘记先 Google,我一搜就有 https://blog.csdn.net/guyongqiangx/article/details/74930951

  • 資深大佬 : bkmi

    因为你 Cipher.getInstance() 传错参数了,看一下文档。

  • 主 資深大佬 : szvone

    @CEBBCAT 大佬,我问的是为啥不会变动

  • 主 資深大佬 : szvone

    @momocraft 因为 rsa 是非对称加密 每次的加密结果不是应该要变动才对吗

  • 主 資深大佬 : szvone

    @bkmi 有个问题就是如果不用安卓的话,用 Java 跑,他会变动

  • 資深大佬 : CEBBCAT

    @szvone 大哥,我给你提供了两个信息:

    1. Google 就有
    2. 有人详细调查了为什么他那边回回不同

    拿出你的主观能动性来啊!

  • 資深大佬 : CEBBCAT

    @szvone 我吊,谁说非对称就要回回不一样了?

  • 資深大佬 : webshe11

    把 a() 改成 random() 保证回回都不一样(滑稽

  • 資深大佬 : crab

    填充用的全 0 或者 F 不是随机数吧

  • 資深大佬 : yicong135

  • 資深大佬 : nvkou

    输入不变输出还变?还是不是一一映射了?非对称是不能推导出私钥而保证加密方安全。

  • 資深大佬 : xiri

    你对非对称加密貌似有什么误解

  • 資深大佬 : geelaw

    @momocraft #2
    @CEBBCAT #9
    @nvkou #13
    @xiri #14

    一个定理:一个具有最基本安全性(具体来说是语义安全)的非对称加密算法必须满足,正常生成的密钥,加密同一消息两次,密文相同的概率必须非常小。

    回到题主的问题,我个人并不是很懂 Java 的 API,根据文档字符串是 RSA 的时候使用 PKCS#1 定义的 RSA 变换,我个人也不是很懂 PKCS#1,一个可能的理解是 Android 上该算法的实现是 RSA 陷门函数,并不是一个安全的加密算法。

  • 資深大佬 : isnullstring

    私钥 解密
    公钥 加密
    那你的公钥变了没?

  • 資深大佬 : mxT52CRuqR6o5

    @geelaw 是密码体制而不是非对称加密算法吧

  • 資深大佬 : geelaw

    @mxT52CRuqR6o5 #17 和非对称密码学紧密相关的算法可以总称为“非对称密码(学)算法”,而“非对称加密算法”是指非对称加密方案 (public-key encryption scheme) 的加密算法 (encryption algorithm)。

  • 資深大佬 : baicheng10

    @geelaw #14 正常生成的密钥,加密同一消息两次,密文相同的概率必须非常小 —> 相同的密钥,加密同一消息数次,密文各不相? 安卓上一个奇怪的 rsa,每次加密结果都一样 你这是“量子加密”么 安卓上一个奇怪的 rsa,每次加密结果都一样 ……

  • 資深大佬 : ThirdFlame

    非对称加密 没有说在明文 和 秘钥不改变的情况下,密文会变的说法。

    但是有些加密函数自带了填充,比如 最优非对称加密填充(OAEP),那么每次加密时会对明文进行了填充(每次填充都不一样),就导致了密文每次都会发生变化。

  • 資深大佬 : bagel

    Padding 导致的。说白了就是没有真正理解 RSA 加密算法。

    上面 geelaw 已经指出来了,还一堆人在那不懂装懂。另外,geelaw 你最后“可能的理解”是错的,Android 上的 API 是正确的,只是有些人不会用又不愿意读文档而已。

  • 資深大佬 : ThirdFlame

    @geelaw
    @baicheng10
    在没有填充的情况下,明文 秘钥不变的情况下,密文不变。
    在最优非对称加密填充(OAEP) 下 明文 秘钥不变的情况下,密文会变。根本原因是明文被填充了一些东西(每次还不一样),其实也就是明文变化了,所以导致了密文变化。
    有些填充方式是固定的,不会导致每次填充后的明文变化,也就不会产生密文的变化。

  • 資深大佬 : CEBBCAT

    @baicheng10 他这个还真没说错,你去搜索一下 语义安全 就明白了,或者去看这个链接: https://www.zhihu.com/question/305995210

  • 資深大佬 : mxT52CRuqR6o5

    @geelaw 能说一下 [一个具有最基本安全性(具体来说是语义安全)的非对称加密算法必须满足,正常生成的密钥,加密同一消息两次,密文相同的概率必须非常小] 这个说法是从哪来的吗?查了半天没查到

  • 資深大佬 : KingPL

    sm2 每次加密后不一样,但依旧可以重放攻击,正常后端解密后也需要验签,防重放攻击

  • 資深大佬 : baicheng10

    @CEBBCAT #22 明白了,谢谢。

  • 資深大佬 : geelaw

    @bagel #21 根据 #7 的说法,另一个 Java runtime 的实现是不同的,我猜另一个实现是 Sun 或者 Oracle 的,这个实现出现如此严重错误的可能感觉也不大。

    @baicheng10 #19 如果你加密同一条消息多项式次,密文以极高的概率各不相同。
    @ThirdFlame #20 确定性加密并不安全。
    @mxT52CRuqR6o5 #24 你可以参考 #23 的链接。

  • 資深大佬 : ThirdFlame

    @geelaw 安全不安全 不是我所说的那段话所要讨论的。 我只是想说明 为啥非对称加密 其实是不会变的。 而有些函数,为啥会变。

    你的问题 其实就是要去看 那个函数实现里面有没有填充。 而不是问 “RSA 加密的话不是每次都会变动吗,为啥这个就不会变动呢?”

  • 資深大佬 : xiri

    @geelaw
    我姑且是学过密码学的。
    根据我学到的原理,rsa 加密时所取的参数都是确定值,在明文不变的情况下计算出来的结果不可能会发生变化。
    你说的“每次加密结果不同”貌似是同属于非对称密码体制下的椭圆曲线加密算法才有的性质。
    椭圆曲线加密除了明文和一些必要参数,还用到了一个随机选取的 k 值。这个 k 值不需要让解密者知道,不会影响解密,但 k 值的变化会影响密文的结果。

  • 資深大佬 : xiri

    @xiri 我这里只是从纯理论层面说明,不考虑实际应用时存在的填充之类的行为

  • 資深大佬 : geelaw

    @ThirdFlame #28 主觉得自己选择了 RSA 加密算法,应该同一明文得到很多不同的密文,回复中问为什么非对称加密都要明文有不同的密文。一个不安全的非对称加密算法(仅符合语法和正确性)当然没有必要有随机化的加密算法。显然讨论不安全的加密算法是否非要随机并不是上一些回复的疑惑。

    另外,那个问题不是“我的问题”。

    @xiri #29

    之前我一直是说结论,懒得提症结,觉得还是需要点明一下:很多回复混淆了 RSA 陷门函数和(安全的) RSA 加密。

  • 主 資深大佬 : szvone

    @bagel
    @geelaw
    @xiri
    @ThirdFlame
    @CEBBCAT

    感谢各位大佬的回复,我遇到的问题是,如果在电脑上面跑 main 函数,那么这个加密结果是会变动,如果在安卓上用按钮事件触发,这个加密结果始终不变,在无法改动安卓代码的情况下,服务端应该如何编写这个加密过程

  • 資深大佬 : Delon

    上就 @geelaw 一个明白人,主要查问题也要从 padding 上面查

  • 資深大佬 : Delon

    收回第一句,上还是挺多明白人的,我眼瞎

  • 資深大佬 : jacklin96

    @geelaw 看你的头像好像很眼熟 然后去 fb 看了一眼 发现你躺在我的推荐好友列表里

  • 資深大佬 : 3dwelcome

    RSA 有两种填充。
    第一种叫签名报文(PKCS#1 Type 01),保证每次签名后,结果都不变,好知道谁签名的(比如 TLS 里的 RSA)。
    第二种才叫加密((PKCS#1 Type 02),保证每次加密后,结果都变化,增加安全性。

  • 資深大佬 : bagel

    我再详细说下吧

    @szvone #32 你在 Android 上面调用 init 方式没有指定 iv,这是为啥每次结果都一样的原因。安全的做法是像下面这样调用
    cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));

    @geelaw #27 Android 和 Java 上面实现不同,Android 默认没有用随机 iv 填充。这是实现的差异,两者都是符合规范的。spec 里原文是
    If this cipher requires any algorithm parameters that cannot be derived from the given key, the underlying cipher implementation is supposed to generate the required parameters itself (using provider-specific default or random values)

    参考: https://stackoverflow.com/questions/31036780/android-cryptography-api-not-generating-safe-iv-for-aes#31037133

  • 主 資深大佬 : szvone

    ^_^已经完全理解,感谢各位大佬不吝赐教
    @bagel
    @3dwelcome

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具