2

私は VB.NET から PasswordDeriveBytes の実装を再作成しようとしていますが、これまでのところ iOS Objective C コードに実装しており、Java 実装とは異なる結果が得られています。

PasswordDeriveBytes の実装を再作成しようとする理由は、クライアント サーバー側がそれを使用してデータを暗号化/復号化しているためです。Java 実装は期待される暗号化された値を返し、サーバーによって正常に復号化されています。ただし、iOS ObjC 実装から返される値は正しくありません。

以下は、この回答から取られた、コンストラクターの Java 実装です: Java と C# の間の暗号化の違い

public static class PasswordDeriveBytes{

private final MessageDigest hash;

private final byte[] firstToLastDigest;
private final byte[] outputBuffer;

private int position = 0;

public PasswordDeriveBytes(String password, byte[] salt, int iterations) {
    try {
        this.hash = MessageDigest.getInstance("SHA-1");

        this.hash.update(password.getBytes("UTF-8"));
        this.hash.update(salt);
        this.firstToLastDigest = this.hash.digest();
        // At this point, the Obj-C and Java values are the same
        // this.firstToLastDigest = b8fa3d36....

        for (int i = 1; i < iterations - 1; i++) {
            System.out.println( "  Iterate " + i);
            hash.update(firstToLastDigest);
            hash.digest(firstToLastDigest, 0, firstToLastDigest.length);
        }

        this.outputBuffer = hash.digest(firstToLastDigest);
        // However at this point, they become different
        // Java has outputBuffer = f498e100...
        // Obj-C has outputBuffer = <d7d5fa71...

    } catch (UnsupportedEncodingException|NoSuchAlgorithmException | DigestException e) {
        throw new IllegalStateException("SHA-1 digest should always be available", e);
    }
}

以下は、このライブラリを使用したコンストラクターの目的の C コードです: https://github.com/TakahikoKawasaki/nv-ios-digest

@implementation PasswordDeriveBytesObjC
{
    SHA1 *hash;
    Byte *firstToLastDigest;
    Byte *outputBuffer;

    int position;
}

- (instancetype)initWithPassword:(NSString *)password salt:(NSData *)salt iterations:(int)iterations
{
    self = [[[self class] alloc] init];
    if (self){
        hash = [[SHA1 alloc] init];

        const char* ASCIIpassword = [password cStringUsingEncoding:NSUTF8StringEncoding];
        NSData *passwordData = [NSData dataWithBytes:ASCIIpassword length:strlen(ASCIIpassword)];

        [hash updateWith:[passwordData bytes] length:(CC_LONG)[passwordData length]];
        [hash updateWith:[salt bytes] length:(CC_LONG)[salt length]];
        firstToLastDigest = [hash final];
        // At this point, the Obj-C and Java values are the same
        // firstToLastDigest = <b8fa3d36....

        for ( int i = 1; i < iterations - 1; i++ ){
            [hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)];
        }

        [hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)];
        outputBuffer = [hash final];  
        // However at this point, they become different
        // Java has outputBuffer = f498e100...
        // Obj-C has outputBuffer = <d7d5fa71...

    }
    return self;
}

私が調査した限りでは、Java の実装はObj-Chash.digest(input)と同じですが、異なる結果が得られています。[hash updateWith:firstToLastDigest length:(CC_LONG)strlen(firstToLastDigest)]; outputBuffer = [hash final];

現時点では、なぜそれらが異なる値を取得するのかについて他に考えがありません。そのため、あらゆる種類のガイダンスや提案を歓迎します。

4

1 に答える 1