android Pbkdf2,在C夏普的AES加密和在Android中使用PBKDF2WithHmacSHA1解密
以下是C#Cryptor的代码,它使用256位长密钥,128位长IV,5000次迭代。它使用Rfc2898DeriveBytes类,因此它与Android中的PBKDF2WithHmacSHA1相同。
C#Cryptor的解密函数将其作为IV作为256位长密钥的(反向的)前128位。
namespace CompanyName.Framework.Encryption
{
internal class SymmetricCryptor : ISymmetricCryptor
{
internal static int KeyLengthInBytes = 32;
internal int Iterations = 5000;
#region Private Fields
// RijndaelManaged aes; old version
AesManaged aes;
int IVLength = KeyLengthInBytes >> 1;
#endregion Private Fields
#region Internal Constructors
internal SymmetricCryptor()
{
aes = new AesManaged
{
Mode = CipherMode.CBC,
KeySize= KeyLengthInBytes<<3,
Padding = PaddingMode.PKCS7,
};
//aes.KeySize = KeyLengthInBytes << 3;
//aes.Padding = PaddingMode.Zeros; //PKCS7 can not be used with stream
}
#endregion Internal Constructors
#region Public Methods
public byte[] Decrypt(byte[] cryptedData, string password, IVMode ivmode)
{
using (MemoryStream ms = new MemoryStream(cryptedData))
{
using (MemoryStream data = new MemoryStream())
{
Decrypt(ms, data, password,ivmode);
return data.ToArray();
}
}
}
public void Encrypt(Stream data, Stream trgStream, string password, IVMode ivmode)
{
try
{
var key = GetKey(password);
var iv = (ivmode == IVMode.Auto)
?key.GetBytes(IVLength).Reverse().ToArray()
: new byte[IVLength];
var dc = aes.CreateEncryptor(key.GetBytes(KeyLengthInBytes), iv);
using (CryptoStream cryptor = new CryptoStream(trgStream, dc, CryptoStreamMode.Write))
{
data.CopyTo(cryptor);
cryptor.FlushFinalBlock();
cryptor.Close();
}
}
catch (Exception)
{
throw new InvalidOperationException("Invalid password.");
}
}
public void Decrypt(Stream cryptedData, Stream trgStream, string password, IVMode ivmode)
{
try
{
var key= GetKey(password);
var iv = (ivmode == IVMode.Auto)
? key.GetBytes(IVLength).Reverse().ToArray()
: new byte[IVLength];
var dc = aes.CreateDecryptor(key.GetBytes(KeyLengthInBytes),iv);
using (CryptoStream cryptor = new CryptoStream(cryptedData, dc, CryptoStreamMode.Read))
{
cryptor.CopyTo(trgStream);
cryptor.Close();
}
}
catch (Exception)
{
throw new InvalidOperationException("Invalid password.");
}
}
public byte[] Encrypt(byte[] data, string password, IVMode ivmode)
{
using (MemoryStream ms = new MemoryStream(data))
{
using (MemoryStream cData = new MemoryStream())
{
Encrypt(ms, cData, password,ivmode);
return cData.ToArray();
}
}
}
#endregion Public Methods
#region Private Methods
private Rfc2898DeriveBytes GetKey(string password)
{
try
{
var iv =
CompanyName.Framework.Cryptography.Digest.SHA1.Compute(password);
return new Rfc2898DeriveBytes(password, iv, Iterations);
}
catch (Exception)
{
throw;
}
}
#endregion Private Methods
}
}
我的Android Cryptor,它试图解密由上述C夏普Cryptor看起来像这样加密的消息,我试图将C夏普Cryptor的解密方法,包括:
public class Cryptor {
private static final String TRANSFORMATION = "AES/CBC/PKCS7Padding";
private static final String AES = "AES";
private static final String RANDOM_ALGO = "SHA1PRNG";
private static final int KEY_LENGTH_IN_BITS = 256;
private static final int IV_LENGTH = 16;
private static final int PBE_ITERATION_COUNT = 5000;
private static final int PBE_SALT_LENGTH_INT_BITS = 128;
private static final String PBE_ALGO = "PBKDF2WithHmacSHA1";
public static byte[] generateKeyFromPassword(String password, int Size) throws GeneralSecurityException {
byte[] salt = generateSalt();
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, Size);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(PBE_ALGO);
byte[] data = keyFactory.generateSecret(keySpec).getEncoded();
return data;
}
private static byte[] generateSalt() throws GeneralSecurityException {
return randomBytes(PBE_SALT_LENGTH_INT_BITS);
}
private static byte[] randomBytes(int length) throws GeneralSecurityException {
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGO);
byte[] b = new byte[length];
random.nextBytes(b);
return b;
}
public static byte[] decrypt(byte[] cipherText, String password) throws GeneralSecurityException {
byte[] keyBytes = generateKeyFromPassword(password, 256);
byte[] ivBytes = generateKeyFromPassword(password, 128);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
ivBytes = reverse(ivBytes);
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES);
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] decrypted = cipher.doFinal(cipherText);
return decrypted;
}
public static byte[] reverse(byte[] array) {
if (array == null) {
return null;
}
int i = 0;
int j = array.length - 1;
byte tmp;
while (j > i) {
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
j--;
i++;
}
return array;
}
但它没有工作,当最后被称为我得到一个
javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT
例外。我不知道我在做什么错,因为我在Android中的Decrypt方法与C Sharp中的Decrypt方法完全相同:首先,我从由Csharp服务器和我共享的密码生成密钥。然后我生成一个随机的128位IV,反转它不是必须的,但C Sharp实现反转它,所以我也这样做。谁能告诉我我做错了什么?这里是我使用Cryptor背景:
//open the client channel, read and return the response as byte[]
Channel clientChannel = new Channel(serverAddress);
byte[] result = clientChannel.execute(serviceID.toString(), data);
//result[] is encrypted data. firstTen is the shared Password
byte[] decrypted = Cryptor.decrypt(result, firstTen);
服务器返回结果为Base64加密,通过它进行解密之前,我通过结果[]数组:它配备为Base64字符串 。我得到的结果[]数组通过:
Base64.decode(result, Base64.NO_WRAP);
2016-03-08
Gravity
+1
而不是试图找出C#和Android之间的区别,你最好先解决你的加密问题。初始化向量应该是随机数据,不依赖于密码。否则,它不能达到目的,因为相同的纯文本和密码将始终导致相同的输出。 PBKDF2是为了散列需要存储的密码而构建的。当你从密码中得到盐时,你会失败盐析的目的。而在目前的情况下,我根本看不到PBKDF2的任何需求。什么是“反向”?你认为它会增加安全性吗? –
+0
是的你是对的,我已经更新了我的代码,现在随机产生一个128位的IV。在C Sharp Code中,它已经随机生成。但我仍然得到提到的例外。你是什么意思,你没有看到PBKDF2的需要。我们与C Sharp服务器有共享密码,我需要使用这个共享密码来生成密钥和IV密码?除了使用PBKDF2以外,我该怎么做?反转是没有必要的,但服务器做到了,所以我也做到了。 C代码不是我的代码,Java代码是我的代码 –
+0
如果您使用密码生成salt或IV,则您尚未理解salt和IV的用途。它打败了它的目的。请研究加密的基础知识并重新访问您的设计。 (对不起,我太生硬了......) –
android Pbkdf2,在C夏普的AES加密和在Android中使用PBKDF2WithHmacSHA1解密相关推荐
- android、ios、php之间AES加密解密
使用原因: 因为在项目中,需要在与客户端(IOS,Android)交互的时候,保存一些私有信息,不被别人看到,所以,使用了比较流行的可以反向加解密的AES. PHP 源码 <?php$aes = ...
- android开发 java与c# 兼容AES加密
由于android客户端采用的是AES加密,服务器用的是asp.net(c#),所以就造成了不一致的加密与解密问题,下面就贴出代码,已经试验过. using System; using System. ...
- AES加密:PHP与Java互通,解密准确
AES加密:PHP与Java互通 提交表单中含大写字母解密不正确 AES加密:PHP与Java互通 参考网址:https://www.cnblogs.com/libo0125ok/p/7668026. ...
- Android中的AES加密-下
本文为笔记,记录,写记录后为了方便查阅也为了能更好的记住 参考 什么是AES算法? 前言 本章主要是针对AES加密的原理过程进行梳理.不在于细节,了解各个参数和类的功能来帮助我们再加密是更好的选择如何 ...
- 记一次Python与C#的AES加密对接
前言 这几天做自动化测试的同事找到我,说是帮她看看有个AES加密的问题要怎么处理. 大概就是文档中贴了一段C#的AES加密代码,然后她要翻译成python的版本,去做一些测试相关的工作. 在我印象中, ...
- Java使用AES加密解密
AES加密机制: 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准. 这个标准用来替代原先的 ...
- Java中的AES加密和解密(CBC模式)
通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法.在本文中,我们将讨论Java中具有CBC模 ...
- 每日一课 | AES加密和解密(CBC模式)
通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法.在本文中,我们将讨论Java中具有CBC模 ...
- MySQl数据库使用AES加密解密配Java代码使用
MySQl数据库加密解密 待加密字段varchar INSERT INTO base_info(id,school_db_host) VALUES('1111254',HEX(AES_ENCRYPT( ...
最新文章
- .net下的富文本编辑器FCKeditor的配置方法(图)原创
- 连载-第1章绪论 1.2嵌入式处理器
- 【数据结构】C语言栈的基本操作
- 【Android 逆向】Android 进程注入工具开发 ( 调试进程中寄存器的作用 | 通过 EIP 寄存器控制程序运行 | EIP 寄存器的存档与恢复 )
- CompletableFuture 实现异步计算
- muduo网络库学习(一)对io复用的封装Poller,面向对象与基于对象
- python 微信支付接口 详解_Python支付接口汇总大全(包含微信、支付宝等,长期更新、欢迎补充)...
- 听障学生计算机课本,面向听障学生程序设计的计算机教学辅助系统
- Linux多线程同步
- Laya ui 控件
- 刘兴亮 -- IT博客-中国最具人气的IT博客-赛迪网IT人家园
- PHP面试注意事项与问题
- iOS app发布ERROR ITMS-90096
- Cortex M3 Bit-banding简介
- 九阴真经Ambari——3.安装并配置MariaDB
- 实现图片染色效果的三种方式
- 苹果最新发布的16 英寸 MacBook Pro有哪些亮点和不足之处?
- 从入门到精通,看了这篇文章,你离老黑的路就不远了
- 海信html501n手机,专为中老年人设计的智能手机,海信T50确实不简单
- 微信页面触发返回按钮回到聊天界面
热门文章
- 2017 上海计算机一级,2017年上海计算机一级考试试题
- 常用的全角符号和半角符号
- 如何在不丢失格式的情况下将 Excel 转换为 PDF?
- 麒麟V10 安装信创国产达梦数据库
- HDU1596find the safest road(floyd)
- CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://mirrors.tuna.tsinghua.edu.cn/anaconda错误
- vue获取实时服务器系统信息,vue获取服务器地址
- 实验二 交换机和路由器的使用
- python爬取知乎话题:日常穿jk制服是怎样一种体验?下的所有图片
- 啊噗嗯 demo调试记录