【问题标题】:Decrypting a String Encrypted on an Android device解密在 Android 设备上加密的字符串
【发布时间】:2017-10-08 01:25:10
【问题描述】:

在 Android 4.4 设备上,字符串已使用 spring-android-auth 1.0.1.RELEASE 模块中的 org.springframework.security.crypto.encrypt.AndroidEncryptors 类加密。比如……

// naturally, salt and password are normally different
String salt = "75f4c92894b2f3e7";
String password = "password";
org.springframework.security.crypto.encrypt.TextEncryptor encryptor = org.springframework.security.crypto.encrypt.AndroidEncryptors.text(password, salt);
String encryptedString = encryptor.encrypt("hello");

在一次运行中,encryptedString 解析为“1ee3c42c9b986d30cd88da37f29bc3b9e93e3defdb76a2b23 72a47276152e2bd”。

该字符串随后被发布到 Spring Web 应用程序,托管在 tomcat 7 服务器上,在 JDK 1.6.0_32 上运行(请注意,已安装 JCE Unlimited Strength Jurisdiction Policy Files)。然后我尝试使用 spring-security-crypto 3.2.0.RELEASE 模块中的 org.springframework.security.crypto.encrypt.Encryptors 类解密该字符串...

// naturally, the salt and password values used here are the same as the ones used on the android device
String salt = "75f4c92894b2f3e7";
String password = "password";
org.springframework.security.crypto.encrypt.TextEncryptor encryptor = org.springframework.security.crypto.encrypt.Encryptors.text(password, salt);
String decryptedString = encryptor.decrypt("1ee3c42c9b986d30cd88da37f29bc3b9e93e3defdb76a2b2372a47276152e2bd");

不幸的是,当调用解密方法时,会引发以下异常...

java.lang.IllegalStateException: Unable to invoke Cipher due to bad padding
    at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:125)
    at org.springframework.security.crypto.encrypt.AesBytesEncryptor.decrypt(AesBytesEncryptor.java:75)
    at org.springframework.security.crypto.encrypt.HexEncodingTextEncryptor.decrypt(HexEncodingTextEncryptor.java:40)
    at local.encryption.Decryption.main(Decryption.java:18)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:121)
    ... 3 more

如果我在服务器上加密和解密字符串,一切正常。这似乎表明 AndroidEncryptor 和 Encryptor 类没有使用相同的算法,尽管 API 说它们都使用 256 位 AES 算法并且它们都使用 PKCS #5 的 PBKDF2(基于密码的密钥派生函数)派生密钥#2)。

当我深入研究 AndroidEncryptor 类时,我发现它使用“PBEWITHSHA256AND256BITAES-CBC-BC”算法。然而,Encryptor 类使用“PBKDF2WithHmacSHA1”算法。

有人对前进的道路有什么建议吗?

【问题讨论】:

  • 请注意,针对 Android 项目的 Spring 提出了错误请求...更多信息可在此处获得...jira.spring.io/browse/…

标签: java android encryption spring-security


【解决方案1】:

在我正在使用的 Android 上

compile group: 'org.springframework.security', name: 'spring-security-crypto', version: '3.1.0.RELEASE'

在我正在使用的 Spring-Backend 上

compile "org.springframework.security:spring-security-core:4.2.3.RELEASE"

我给你的例子看起来像:

val password = "MY_PASSWORD"
val salt = KeyGenerators.string().generateKey()
val encryptor = Encryptors.text(password, salt)
val textToEncrypt = "kotlin-rocks"
val encryptedText = encryptor.encrypt(textToEncrypt)

val decryptor = Encryptors.text(password, salt)
val decryptedText = decryptor.decrypt(encryptedText)


println("Salt: \"" + salt + "\"")
println("Original text: \"" + textToEncrypt + "\"")
println("Encrypted text: \"" + encryptedText + "\"")
println("Decrypted text: \"" + decryptedText + "\"")

如果您在 Android 上运行代码,您将得到以下随机结果:

Salt: "2578bfa1cb682f17"
Original text: "kotlin-rocks"
Encrypted text: "bdfdfff122accfadc0ad5449bb9c93ceedd2380b2e7f8cd19d2ce03daec4218e"
Decrypted text: "kotlin-rocks"

现在您必须将 salt加密文本 发送到服务器。服务器将同时使用它们,现在可以解密密码。密码的实现可以一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 2015-07-09
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多