.Net代码:
public string AESEncrypt(string clearText,string key)
{
string EncryptionKey = key; // "MAKV2SPBNI99212";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
int iterations = 1024;
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }, iterations);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
快速代码:
// "MAKV2SPBNI99212" Key
func AESEncryptedString( withKey key : String) -> String? {
let salt : Array <UInt8> = [0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76]
let saltData = NSData(bytes: salt, length: 13)
let myPassData : NSData = key.data(using: String.Encoding.utf8)! as NSData
var key = [UInt8](repeating: 0, count: 48)
var initialVector = [UInt8](repeating: 0, count: 16)
let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), ptrData, myPassData.length, ptrSalt, saltData.length, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), 1024, keyPtr, 48)
initialVector = Array(key[32..<48])
key = Array(key[0..<32])
let keyD = Data(bytes: key)
let ivD = Data(bytes:initialVector)
let rawData = self.data(using: String.Encoding.unicode)
let encryptedData = testCrypt(data:rawData!, keyData:keyD, ivData:ivD, operation:kCCEncrypt)
let decryptedData = testDeCrypt(data:encryptedData, keyData:keyD, ivData:ivD, operation:kCCDecrypt)
let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf16)!
print("Encrypted Data: \(encryptedData.base64EncodedString()) \n with count: \(encryptedData.base64EncodedString().characters.count)")
print("Decrypted: \(decrypted)")
let encryptedString = encryptedData.base64EncodedString()
return encryptedString
}
func testCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
let buffer_size : size_t = (data as NSData).length + kCCBlockSizeAES128
let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions( kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySizeAES256)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (keyData as NSData).bytes, keyLength, (ivData as NSData).bytes, (data as NSData).bytes, (data as NSData).length, buffer, buffer_size, &num_bytes_encrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess){
let myResult: NSData = NSData(bytes: buffer, length: num_bytes_encrypted)
free(buffer)
let keyData: NSData = myResult
let hexString = (keyData as Data).base64EncodedString()
print(hexString)
return myResult as Data
}else{
free(buffer)
return Data()
}
}
func testDeCrypt(data:Data, keyData:Data, ivData:Data, operation:Int) -> Data {
let decryptedData = NSMutableData(length: (data as NSData).length)
var num_bytes_decrypted: size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let keyLength = size_t(kCCKeySizeAES256)
let Crypto_status: CCCryptorStatus = CCCrypt(operation, algoritm, options, (keyData as NSData).bytes, keyLength, (ivData as NSData).bytes, (data as NSData).bytes, (data as NSData).length, decryptedData?.mutableBytes, (decryptedData?.length)!, &num_bytes_decrypted)
if UInt32(Crypto_status) == UInt32(kCCSuccess){
decryptedData?.length = num_bytes_decrypted
return decryptedData! as Data
} else {
return Data()
}
}
我们能够在 Swift 中加密和解密数据,但 .Net 代码的加密数据未在 Swift 中解密。如果代码有任何问题,请告诉我。我们尝试在 .net 中解密 swift 的加密数据它的工作很好,但我们无法解密 .net 数据。请帮助我们。我几乎尝试了所有可用的解决方案。
最佳答案
就我测试您的代码(C# 和 Swift)而言,导致问题的主要区别在于字符串编码。
但在去那里之前,我需要注意您的代码充满了关于使用 Data 的不良做法。和 NSData , 传递 Data 的地址或 [UInt8]等等,其中一些很关键。
最重要的是这一行:
let buffer = UnsafeMutablePointer<NSData>.allocate(capacity: buffer_size)
你需要分配一个buffer_size字节内存区域,你不想要 buffer_size引用 NSData .
其他一些脆弱的线条:
let ptrData = myPassData.bytes.assumingMemoryBound(to: Int8.self)
let ptrSalt = saltData.bytes.assumingMemoryBound(to: UInt8.self)
let keyPtr = UnsafeMutablePointer<UInt8>(mutating: key)
这些行在很大程度上取决于当前 Swift 实现的代码生成以及您当前的设置。
简单地说,令人惊讶的是你的代码似乎没有崩溃。
因此,我开始按如下方式重写您的 Swift 代码:
func testCrypt(data: Data, keyData: Data, ivData: Data, operation:Int) -> Data {
assert(keyData.count == Int(kCCKeySizeAES128) || keyData.count == Int(kCCKeySizeAES192) || keyData.count == Int(kCCKeySizeAES256))
let buffer_size = data.count + kCCBlockSizeAES128
var buffer: [UInt8] = Array(repeating: 0, count: buffer_size)
var num_bytes_encrypted : size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptoStatus = keyData.withUnsafeBytes {keyDataBytes in
ivData.withUnsafeBytes {ivDataBytes in
data.withUnsafeBytes {dataBytes in
CCCrypt(operation, algoritm, options, keyDataBytes, keyData.count, ivDataBytes, dataBytes, data.count, &buffer, buffer_size, &num_bytes_encrypted)
}
}
}
if cryptoStatus == CCCryptorStatus(kCCSuccess){
let myResult = Data(bytes: buffer, count: num_bytes_encrypted)
return myResult
} else {
return Data()
}
}
func testDeCrypt(data: Data, keyData: Data, ivData: Data, operation: Int) -> Data {
assert(keyData.count == Int(kCCKeySizeAES128) || keyData.count == Int(kCCKeySizeAES192) || keyData.count == Int(kCCKeySizeAES256))
var decryptedData = Data(count: data.count)
var num_bytes_decrypted: size_t = 0
let operation = CCOperation(operation)
let algoritm = CCAlgorithm(kCCAlgorithmAES)
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptoStatus = keyData.withUnsafeBytes {keyDataBytes in
ivData.withUnsafeBytes {ivDataBytes in
data.withUnsafeBytes {dataBytes in
decryptedData.withUnsafeMutableBytes {decryptedDataBytes in
CCCrypt(operation, algoritm, options, keyDataBytes, keyData.count, ivDataBytes, dataBytes, data.count, decryptedDataBytes, decryptedData.count, &num_bytes_decrypted)
}
}
}
}
if cryptoStatus == CCCryptorStatus(kCCSuccess) {
decryptedData.count = num_bytes_decrypted
return decryptedData
} else {
return Data()
}
}
extension String {
func AESEncryptedString(withKey keyString: String) -> String? {
let salt: [UInt8] = [0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76]
var key = [UInt8](repeating: 0, count: 48)
CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2), keyString, keyString.utf8.count, salt, salt.count, CCPseudoRandomAlgorithm(kCCPRFHmacAlgSHA1), 1024, &key, 48)
let initialVector = Array(key[32..<48])
key = Array(key[0..<32])
let keyData = Data(bytes: key)
let ivData = Data(bytes: initialVector)
let rawData = self.data(using: .unicode)!
let encryptedData = testCrypt(data: rawData, keyData: keyData, ivData: ivData, operation: kCCEncrypt)
let decryptedData = testDeCrypt(data: encryptedData, keyData: keyData, ivData: ivData, operation: kCCDecrypt)
let decrypted = String(bytes: decryptedData, encoding: .unicode)!
print("Encrypted Data: \(encryptedData.base64EncodedString()) \n with count: \(encryptedData.base64EncodedString().characters.count)")
print("Decrypted: \(decrypted)")
let encryptedString = encryptedData.base64EncodedString()
return encryptedString
}
}
( String.Encoding.utf16 只是 String.Encoding.unicode 的别名,所以我将使用 .utf16 的行替换为 .unicode 。)
您的 C# 代码将字符串转换为字节数组的部分:
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
生成 Data 的部分在 Swift 中:
let rawData = self.data(using: .unicode)!
这两行生成不同的字节序列,如.unicode符合规范的 UTF-16 表示,其在结果顶部包含 BOM,但 System.Text.Encoding.Unicode不添加 BOM。
因此,更改包含 .unicode 的两行至 .utf16LittleEndian :
let rawData = self.data(using: .utf16LittleEndian)!
let decrypted = String(bytes: decryptedData, encoding: .utf16LittleEndian)!
尝试看看这些更改会带来什么。
关于.net - AES 加密 .net 到 swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43715416/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec
我在加密来self正在使用的第三方供应商的值时遇到问题。他们的指令如下:1)Converttheencryptionpasswordtoabytearray.2)Convertthevaluetobeencryptedtoabytearray.3)Theentirelengthofthearrayisinsertedasthefirstfourbytesontothefrontofthefirstblockoftheresultantbytearraybeforeencryption.4)EncryptthevalueusingAESwith:1.256-bitkeysize,2.25
我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/
在previousquestion中我想出了如何在多个服务器上启动经过密码验证的sshsession来运行单个命令。现在我需要能够执行“sudo”命令。问题是,net-ssh-multi没有分配sudo需要运行的伪终端(pty),导致以下错误:[127.0.0.1:stderr]sudo:sorry,youmusthaveattytorunsudo根据documentation,可以通过调用channel对象的方法来分配伪终端,但是,以下代码不起作用:它会生成上面的“notty”错误:require'net/ssh'require'net/ssh/multi'Net::SSH::Mul