- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
加密字符串的方法大约有 100,000 种。使用 AES、CBC 和 PKCS7 等标准可以使事情变得更容易——但 IV 仍然存在问题。盐、编码等(如 www.Crypto.Stackexchange.com 所述)
对于我的 iOS 项目 (Obj-C),我正在使用 FBEncryptor project这是一种加密字符串的简单且有据可查的方法。但是,我需要能够解密 FBEncryptor 在 Windows 平台上生成的 iOS AES 字符串的代码 - 最好是 VB.NET。
我还没有找到另一个与 FBEncryptor 兼容的 VB.NET 项目。
有人知道任何与 FBEncryptor 一起工作的 VB.NET 加密项目吗?如果不是,那么我需要做什么才能使 Rijndael 托管库(由 Microsoft 提供)与 FBEncryptor 一起使用?
我的 VB.NET 代码使用 Rijndael Managed :
Imports System.Security
Imports System.Security.Cryptography
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Imports System.Text
Module Encrypt2
Public saltBytes As Byte()
Dim hashAlgorithm As String = "SHA1"
Public Sub GenerateSalt()
' Define min and max salt sizes.
Dim minSaltSize As Integer
Dim maxSaltSize As Integer
minSaltSize = 8
maxSaltSize = 8
' Generate a random number for the size of the salt.
Dim random As Random
random = New Random()
Dim saltSize As Integer
saltSize = random.Next(minSaltSize, maxSaltSize)
' Allocate a byte array, which will hold the salt.
saltBytes = New Byte(saltSize - 1) {}
' Initialize a random number generator.
Dim rng As RNGCryptoServiceProvider
rng = New RNGCryptoServiceProvider()
' Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes)
End Sub
Public Function Encrypt(ByVal plainText As String, ByVal keyword As String) As String
Dim hashAlgorithm As String = "SHA1"
Dim passwordIterations As Integer = 128
Dim initVector As String = "@7781157e2629b09"
Dim keySize As Integer = 256
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim plainTextBytes As Byte() = Encoding.ASCII.GetBytes(plainText)
GenerateSalt()
Dim password As New Rfc2898DeriveBytes(keyword, saltBytes, passwordIterations)
Dim keyBytes As Byte() = password.GetBytes(keySize \ 8)
Dim symmetricKey As New RijndaelManaged()
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Dim memoryStream As New MemoryStream()
Dim cryptoStream As New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Clear()
Dim cipherText As String = Convert.ToBase64String(cipherTextBytes)
Return (cipherText)
End Function
Public Function Decrypt(ByVal cipherText As String, ByVal keyword As String) As String
Dim hashAlgorithm As String = "SHA1"
Dim passwordIterations As Integer = 128
Dim initVector As String = "@7781157e2629b09"
Dim keySize As Integer = 256
' Convert strings defining encryption key characteristics into Byte
' arrays. Let us assume that strings only contain ASCII codes.
' If strings include Unicode characters, use Unicode, UTF7, or UTF8
' encoding
Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
' Convert the Ciphertext into a Byte array
Dim cipherTextBytes As Byte() = Encoding.ASCII.GetBytes(cipherText)
' First we must create a password, from which the key will be
' derived. This password will be generated from the specified
' passphrase and salt value. The password will be created using
' the specified hash algorithm. Password creation can be done in
' several iterations
GenerateSalt()
Dim password As New Rfc2898DeriveBytes(keyword, saltBytes, passwordIterations)
' Use the password to generate pseudo-random bytes for the encryption
' key. Specify the size of the key in bytes (instead of bits)
Dim keyBytes As Byte() = password.GetBytes(keySize \ 8)
' Create uninitialized Rijndael encryption object
Dim symmetricKey As New RijndaelManaged()
' It is reasonable to set encryption mode to Cipher Block Chaining
' (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.CBC
' Generate decryptor from the existing key bytes and initialization
' vector. Key size will be defined based on the number of the key
'bytes
Dim decryptor As ICryptoTransform = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)
' Define memory stream which will be used to hold encrypted data.
Dim memoryStream As New MemoryStream(cipherTextBytes)
' Define cryptographic stream (always user Read mode for encryption).
Dim cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
' Since at this point we don't know what the size of decrypted data
' will be, allocate the buffer long enough to hold ciphertext;
' plaintext is never longer than ciphertext
Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {}
' Start decrypting.
Dim decryptedByteCount As Integer = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
' Close both streams
memoryStream.Close()
cryptoStream.Close()
' Convert decrypted data into a string
' Let us assume that the original plaintext string was UTF8-Encoded.
Dim plainText As String = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)
' Return the decrypted string
Return (plainText)
End Function
End Module
您会注意到 IV 是静态的并且密码迭代次数很少。这是因为我不确定如何使用与 FBEncryptor 相同的方法生成 IV。您可能还会注意到,在尝试解密时,字节长度存在问题。
任何帮助将不胜感激!谢谢!
最佳答案
一张纸条。我查看了 FBEncryptor。它使用了一些不好的做法。因此,如果安全性对您很重要,我建议您阅读更多相关内容并选择另一个进行加密的代码(或自行编写)。
FBEncryptor 做以下加密a) 字符串转字节数组(基于UTF8编码)b) 将 key 转换为字节数组(基于 UTF 编码)。c) 仅复制 key 的前 16 个字节d) 创建 IV,它是 0x00 的 16 个字节e) 使用 AES/CBC/PKCS7Padding 和在 d) 中创建的 IV 加密项目 a) 中的字节数组f) 将得到的加密数据转为Base64
它会进行以下解密a) 将加密字符串从 Base64 转换为字节数组b) 将 key 转换为字节数组(基于 UTF 编码)。c) 仅复制 key 的前 16 个字节d) 创建 IV,它是 0x00 的 16 个字节e) 使用 AES/CBC/PKCS7Padding 和在 d) 中创建的 IV 解密项目 a) 中的字节数组f) 使用 UTF8 编码将 e) 中的加密数据转换为字符串
您应该在 VB.NET 中做完全相同的事情。我想你几乎所有的部分- 您将需要删除所有 SHA1 和盐相关的东西并使用步骤 b) 的等价物。你需要研究 PKCS7Padding for VB.NET
关于ios - Obj-C 和 VB.Net 之间的加密兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12030874/
我需要修复 getLineNumberFor 方法,以便如果 lastName 的第一个字符位于 A 和 M 之间,则返回 1;如果它位于 N 和 Z 之间,则返回 2。 在我看来听起来很简单,但我不
您好,感谢您的帮助!我有这个: 0 我必须在每次点击后增加“pinli
Javascript 中是否有一种方法可以在不使用 if 语句的情况下通过 switch case 结构将一个整数与另一个整数进行比较? 例如。 switch(integer) { case
我有一列是“日期”类型的。如何在自定义选项中使用“之间”选项? 最佳答案 请注意,您有2个盒子。 between(在SQL中)包含所有内容,因此将框1设置为:DATE >= startdate,将框2
我有一个表,其中包含年、月和一些数字列 Year Month Total 2011 10 100 2011 11 150 2011 12 100 20
这个问题已经有答案了: Extract a substring between double quotes with regular expression in Java (2 个回答) how to
我有一个带有类别的边栏。正如你在这里看到的:http://kees.een-site-bouwen.nl/ url 中类别的 ID。带有 uri 段(3)当您单击其中一个类别时,例如网页设计。显示了一
这个问题在这里已经有了答案: My regex is matching too much. How do I make it stop? [duplicate] (5 个答案) 关闭 4 年前。 我
我很不会写正则表达式。 我正在尝试获取括号“()”之间的值。像下面这样的东西...... $a = "POLYGON((1 1,2 2,3 3,1 1))"; preg_match_all("/\((
我必须添加一个叠加层 (ImageView),以便它稍微移动到包含布局的左边界的左侧。 执行此操作的最佳方法是什么? 尝试了一些简单的方法,比如将 ImageView 放在布局中并使用负边距 andr
Rx 中是否有一些扩展方法来完成下面的场景? 我有一个开始泵送的值(绿色圆圈)和其他停止泵送的值(簧片圆圈),蓝色圆圈应该是预期值,我不希望这个命令被取消并重新创建(即“TakeUntil”和“Ski
我有一个看起来像这样的数据框(Dataframe X): id number found 1 5225 NA 2 2222 NA 3 3121 NA 我有另一个看起来
所以,我正在尝试制作正则表达式,它将解析存储在对象中的所有全局函数声明,例如,像这样 const a = () => {} 我做了这样的事情: /(?:const|let|var)\s*([A-z0-
我正在尝试从 Intellivision 重新创建 Astro-Smash,我想让桶保持在两个 Angular 之间。我只是想不出在哪里以及如何让这个东西停留在两者之间。 我已经以各种方式交换了函数,
到处检查但找不到答案。 我有这个页面,我使用 INNER JOIN 将两个表连接在一起,获取它们的值并显示它们。我有这个表格,用来获取变量(例如开始日期、结束日期和卡号),这些变量将作为从表中调用值的
我陷入了两个不同的问题/错误之间,无法想出一个合适的解决方案。任何帮助将不胜感激 上下文、FFI 和调用大量 C 函数,并将 C 类型包装在 rust 结构中。 第一个问题是ICE: this pat
我在 MySQL 中有一个用户列表,在订阅时,时间戳是使用 CURRENT_TIMESTAMP 在数据库中设置的。 现在我想从此表中选择订阅日期介于第 X 天和第 Y 天之间的表我尝试了几个查询,但不
我的输入是开始日期和结束日期。我想检查它是在 12 月 1 日到 3 月 31 日之间。(年份可以更改,并且只有在此期间内或之外的日期)。 到目前为止,我还没有找到任何关于 Joda-time 的解决
我正在努力了解线程与 CPU 使用率的关系。有很多关于线程与多处理的讨论(一个很好的概述是 this answer )所以我决定通过在运行 Windows 10、Python 3.4 的 8 CPU
我正在尝试编写 PHP 代码来循环遍历数组以创建 HTML 表格。我一直在尝试做类似的事情: fetchAll(PDO::FETCH_ASSOC); ?>
我是一名优秀的程序员,十分优秀!