2016-10-28 7 views
1

https://github.com/Gurpartap/AESCrypt-ObjC iが使用IOS AESCryptからのNode.jsで復号化メッセージ

print(AESCrypt.encrypt("Start of messsage this ultra long message about how to AES encrypt in node js, message cryptrd with ios AESCrypt! finish", password: "pass")) 

IOSのプリント= "DB6bpsjaoOTuBL/tb0KR81zOD9gQTmiRjP6Jk3H6WB06rKA513d3VEVvD7fJ4Ap54JRB + e0Vcj7IRPZeB1iauc71udvsUIt59gdds/AP6 + qGKLjVBRpo9mD3xcHkZRuSBGjEnjjdfn8vpDER7oBg9ArQL6vvdc5bb3FtJ4wUdRI ="

である場合、私は接頭辞が壊れています

およびAndroidの場合

MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
    digest.update(password.getBytes("UTF-8")); 
    byte[] keyBytes = new byte[32]; 
    System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length); 

    cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
    key = new SecretKeySpec(keyBytes, "AES"); 
    spec = getIV(); 
} 

public AlgorithmParameterSpec getIV() 
{ 
    byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; 
    IvParameterSpec ivParameterSpec; 
    ivParameterSpec = new IvParameterSpec(iv); 

    return ivParameterSpec; 
} 

public String encrypt(String plainText) throws Exception 
{ 
    cipher.init(Cipher.ENCRYPT_MODE, key, spec); 
    byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8")); 
    String encryptedText = new String(Base64.encode(encrypted, Base64.DEFAULT), "UTF-8"); 

    return encryptedText; 
} 

が、私はNode.jsのサーバーに解読しようとしたとき、私は問題がある - 復号化されたメッセージは、接頭辞

bFQAG_V] UCCCQW

メッセージについて=「bFQAG_V] UCCCQWeこの超長いメッセージをクラッシュしましたAES ノードjsで暗号化、メッセージcryptrdでios AESCrypt!フィニッシュ」

は異なる設定を試してみましたが、何もここで

は私のコードは、コードの多くは、これだけの推測を行うことができ不足しているのNode.js

var crypto = require('crypto'); 
var iv = new Buffer(16); 

var encrypt = function(data, key) { 
    var decodeKey = crypto.createHash('sha256').update(key, 'utf-8').digest(); 
    var cipher = crypto.createCipheriv('aes-256-cbc', decodeKey, iv); 
    return cipher.update(data, 'utf8', 'base64') + cipher.final('base64'); 
}; 

var decrypt = function(data, key) { 
    var encodeKey = crypto.createHash('sha256').update(key).digest(); 
    var cipher = crypto.createDecipheriv('AES-256-CBC', encodeKey, iv); 
    var text = cipher.update(data, 'base64', 'utf8')+ cipher.final('utf8') 
    return text; 
}; 

var data = 'DB6bpsjaoOTuBL/tb0KR81zOD9gQTmiRjP6Jk3H6WB06rKA513d3VEVvD7fJ4Ap54JRB+e0Vcj7IRPZeB1iauc71udvsUIt59gdds/AP6+qGKLjVBRpo9mD3xcHkZRuSBGjEnjjdfn8vpDER7oBg9ArQL6vvdc5bb3FtJ4wUdRI=' 
var key = 'pass'; 
var decipher = decrypt(data, key); 

答えて

0

ではありません:

node.jsコードでは、一般的な方法である暗号化されたデータの先頭にIVが付加されており、復号化する前に16バイトのIVを削除していません。

この場合、IVプレフィックスを分割し、それを復号化のIVとして使用します。推奨されないドキュメントのセクションから

例:IVは暗号化されたデータ

aesCBC128Encryptの前に置かれ

CBCモードのAES暗号化ランダムIV(スウィフト3+)

では作成されます。ランダムなIVと暗号化されたコードのプレフィックス。
aesCBC128Decryptは、復号化中に接頭辞付きIVを使用します。

入力はデータであり、キーはデータオブジェクトです。必要に応じてBase64などのエンコードされたフォームが、呼び出し元のメソッドに変換および/または変換する場合。

鍵は、正確に128ビット(16バイト)、192ビット(24バイト)または256ビット(32バイト)の長さでなければなりません。別のキーサイズを使用すると、エラーがスローされます。

PKCS#7 paddingがデフォルトで設定されています。

この例では、一般的な暗号
を必要とすることは、プロジェクトへの橋渡しヘッダを持っていることが必要である:
#import <CommonCrypto/CommonCrypto.h>
は、プロジェクトにSecurity.frameworkを追加します。

これは実動コードではなく、例です。

enum AESError: Error { 
    case KeyError((String, Int)) 
    case IVError((String, Int)) 
    case CryptorError((String, Int)) 
} 

// The iv is prefixed to the encrypted data 
func aesCBCEncrypt(data:Data, keyData:Data) throws -> Data { 
    let keyLength = keyData.count 
    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256] 
    if (validKeyLengths.contains(keyLength) == false) { 
     throw AESError.KeyError(("Invalid key length", keyLength)) 
    } 

    let ivSize = kCCBlockSizeAES128; 
    let cryptLength = size_t(ivSize + data.count + kCCBlockSizeAES128) 
    var cryptData = Data(count:cryptLength) 

    let status = cryptData.withUnsafeMutableBytes {ivBytes in 
     SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes) 
    } 
    if (status != 0) { 
     throw AESError.IVError(("IV generation failed", Int(status))) 
    } 

    var numBytesEncrypted :size_t = 0 
    let options = CCOptions(kCCOptionPKCS7Padding) 

    let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in 
     data.withUnsafeBytes {dataBytes in 
      keyData.withUnsafeBytes {keyBytes in 
       CCCrypt(CCOperation(kCCEncrypt), 
         CCAlgorithm(kCCAlgorithmAES), 
         options, 
         keyBytes, keyLength, 
         cryptBytes, 
         dataBytes, data.count, 
         cryptBytes+kCCBlockSizeAES128, cryptLength, 
         &numBytesEncrypted) 
      } 
     } 
    } 

    if UInt32(cryptStatus) == UInt32(kCCSuccess) { 
     cryptData.count = numBytesEncrypted + ivSize 
    } 
    else { 
     throw AESError.CryptorError(("Encryption failed", Int(cryptStatus))) 
    } 

    return cryptData; 
} 

// The iv is prefixed to the encrypted data 
func aesCBCDecrypt(data:Data, keyData:Data) throws -> Data? { 
    let keyLength = keyData.count 
    let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256] 
    if (validKeyLengths.contains(keyLength) == false) { 
     throw AESError.KeyError(("Invalid key length", keyLength)) 
    } 

    let ivSize = kCCBlockSizeAES128; 
    let clearLength = size_t(data.count - ivSize) 
    var clearData = Data(count:clearLength) 

    var numBytesDecrypted :size_t = 0 
    let options = CCOptions(kCCOptionPKCS7Padding) 

    let cryptStatus = clearData.withUnsafeMutableBytes {cryptBytes in 
     data.withUnsafeBytes {dataBytes in 
      keyData.withUnsafeBytes {keyBytes in 
       CCCrypt(CCOperation(kCCDecrypt), 
         CCAlgorithm(kCCAlgorithmAES128), 
         options, 
         keyBytes, keyLength, 
         dataBytes, 
         dataBytes+kCCBlockSizeAES128, clearLength, 
         cryptBytes, clearLength, 
         &numBytesDecrypted) 
      } 
     } 
    } 

    if UInt32(cryptStatus) == UInt32(kCCSuccess) { 
     clearData.count = numBytesDecrypted 
    } 
    else { 
     throw AESError.CryptorError(("Decryption failed", Int(cryptStatus))) 
    } 

    return clearData; 
} 

使用例:

let clearData = "clearData".data(using:String.Encoding.utf8)! 
let keyData = "keyData89".data(using:String.Encoding.utf8)! 
print("clearData: \(clearData as NSData)") 
print("keyData:  \(keyData as NSData)") 

var cryptData :Data? 
do { 
    cryptData = try aesCBCEncrypt(data:clearData, keyData:keyData) 
    print("cryptData: \(cryptData! as NSData)") 
} 
catch (let status) { 
    print("Error aesCBCEncrypt: \(status)") 
} 

let decryptData :Data? 
do { 
    let decryptData = try aesCBCDecrypt(data:cryptData!, keyData:keyData) 
    print("decryptData: \(decryptData! as NSData)") 
} 
catch (let status) { 
    print("Error aesCBCDecrypt: \(status)") 
} 

出力例:

clearData: <636c6561 72446174 61303132 33343536> 
keyData:  <6b657944 61746138 39303132 33343536> 
cryptData: <92c57393 f454d959 5a4d158f 6e1cd3e7 77986ee9 b2970f49 2bafcf1a 8ee9d51a bde49c31 d7780256 71837a61 60fa4be0> 
decryptData: <636c6561 72446174 61303132 33343536> 

注:
CBCモードのコード例の一つの典型的な問題は、それがランダムの作成と共有を残していることですIVをユーザに提示する。この例はIVの生成を含み、暗号化されたデータの前に置かれ、復号化の間に接頭語IVを使用する。これにより、普通のユーザーはCBC modeに必要な詳細情報を解放します。

セキュリティ上、暗号化されたデータにも認証が必要です。このサンプルコードでは、小規模で他のプラットフォームとの相互運用性を高めるために、このコードでは提供していません。

また、パスワードからキーのキーを派生させたものがありません。PBKDF2を使用することをお勧めします。

安定したマルチプラットフォーム対応の暗号化コードについては、RNCryptorを参照してください。

+0

私は2つのアプリケーション(ios android)を持っていますが、このアプリケーション間のメッセージは機能しますが、サーバー上のメッセージを復号化する必要があります。 、もしあなたがアンドロイドコードを見て、ノードj上で同じものが見えるならば、IVの生成は同じように見えます –

関連する問題