第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

android AES/CTR/NoPadding 中的解密、密碼問題

android AES/CTR/NoPadding 中的解密、密碼問題

jeck貓 2023-06-14 16:18:03
當我在 android Marshmallow(Android 6.0.1) 上使用此代碼時,解密正常,但是當我在帶有 android Oreo(Android 8) 的設備上運行時,解密值不相同并且數(shù)據(jù)不正確。private void decrypt(Cipher cipher, Uri uri) throws Exception {    long a = 113845229;    InputStream inputStream = getContentResolver().openInputStream(uri);    CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);    cipherInputStream.skip(a);    byte[] buffer = new byte[8];    cipherInputStream.read(buffer);}// create cipherprivate Cipher createCipher(byte[] iv, byte[] salt, String password) throws Exception {    IvParameterSpec mIvParameterSpec = new IvParameterSpec(iv);    SecretKeySpec mSecretKeySpec = generate(password, salt);    Cipher mCipher = Cipher.getInstance("AES/CTR/NoPadding");    mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec, mIvParameterSpec);    return mCipher;}// generate keyprivate SecretKeySpec generate(String password, byte[] salt) throws Exception {    MessageDigest md = MessageDigest.getInstance("SHA-256");    md.update(salt);    byte[] key = md.digest(password.getBytes(StandardCharsets.UTF_8));    return new SecretKeySpec(key, "AES");}緩沖區(qū)數(shù)據(jù)在 android 6 中正常,但在 android 8 中數(shù)據(jù)不正確。
查看完整描述

2 回答

?
皈依舞

TA貢獻1851條經(jīng)驗 獲得超3個贊

我相信您正在尋找對 ctr 加密數(shù)據(jù)的隨機訪問;CipherInputStream 中的 Skip 方法只是不這樣做,并且是“獨立于 Android 版本”(仍在使用;自 api 級別1以來未棄用或替換?。?;

查看 CipherInputStream 類文件;它有一些內(nèi)部屬性:

private Cipher cipher;//the cipher you pass to constructor;

// the underlying input stream

private InputStream input;

/* the buffer holding data that have been read in from the

? ?underlying stream, but have not been processed by the cipher

? ?engine. the size 512 bytes is somewhat randomly chosen */

private byte[] ibuffer = new byte[512];//holds encrypted data

// having reached the end of the underlying input stream

private boolean done = false;

/* the buffer holding data that have been processed by the cipher

? ?engine, but have not been read out */

private byte[] obuffer;//a portion of data that's decrypted but not yet read;

// the offset pointing to the next "new" byte

private int ostart = 0;

// the offset pointing to the last "new" byte

private int ofinish = 0;

這就是 skip 在 CipherInputStream 中所做的;


public long skip(long n) throws IOException {

? ? int available = ofinish - ostart;

? ? if (n > available) {

? ? ? ? n = available;

? ? }

? ? if (n < 0) {

? ? ? ? return 0;

? ? }

? ? ostart += n;

? ? return n;

}

它不會加載新數(shù)據(jù)到 obuffer 或 ibuffer;它只跳過 obuffer 中可用的內(nèi)容(只是增加 ostart);


應該這樣做(有改進的余地):


private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv,

? ? final long blockOffset) {

? ? final BigInteger ivBI = new BigInteger(1, iv.getIV());

? ? final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset

? ? ? ? / AES_BLOCK_SIZE));


? ? final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray();

? ? final IvParameterSpec ivForOffset;

? ? if (ivForOffsetBA.length >= AES_BLOCK_SIZE) {

? ? ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - AES_BLOCK_SIZE,

? ? ? ? ? ? AES_BLOCK_SIZE);

? ? } else {

? ? ? ? final byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE];

? ? ? ? System.arraycopy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE

? ? ? ? ? ? - ivForOffsetBA.length, ivForOffsetBA.length);

? ? ? ? ivForOffset = new IvParameterSpec(ivForOffsetBASized);

? ? }

? ? return ivForOffset;

}

long offset = 113845229;// aka a

private void decrypt(Cipher cipher, Uri uri) throws Exception {

? ? long skip_this_much=offset-(offset%16);

? ? InputStream inputStream = getContentResolver().openInputStream(uri);

? ? do{

? ? ? ? skip_this_much=skip_this_much-inputStream.skip(skip_this_much);//InputStream.skip does not necessarily skip as much as specified in parameter and returns the actually skipped value;

? ? }while(skip_this_much!=0);//not there yet; keep skipping;

? ? CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);

? ? int read_this_much=8;

? ? byte[] buffer=new byte[read_this_much+(offset%16)];

? ? cipherInputStream.read(buffer,0,read_this_much+(offset%16));//improve this yourself

? ? buffer= Arrays.copyOfRange(buffer,offset%16,read_this_much+(offset%16));

}

// create cipher for offset

private Cipher createCipher(byte[] iv, byte[] salt, String password) throws Exception {

? ? IvParameterSpec mIvParameterSpec = new IvParameterSpec(iv);

? ? SecretKeySpec mSecretKeySpec = generate(password, salt);

? ? Cipher mCipher = Cipher.getInstance("AES/CTR/NoPadding");

? ? mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec, calculateIVForOffset(mIvParameterSpec,offset));

? ? return mCipher;

}

// generate key

private SecretKeySpec generate(String password, byte[] salt) throws Exception {

? ? MessageDigest md = MessageDigest.getInstance("SHA-256");

? ? md.update(salt);

? ? byte[] key = md.digest(password.getBytes(StandardCharsets.UTF_8));

? ? return new SecretKeySpec(key, "AES");

}


查看完整回答
反對 回復 2023-06-14
?
紅顏莎娜

TA貢獻1842條經(jīng)驗 獲得超13個贊

經(jīng)過研究我得出結(jié)論。你應該用特定的密碼實現(xiàn) InputStream。


private static final int AES_BLOCK_SIZE = 16;

private InputStream mUpstream;

private Cipher mCipher;

private SecretKeySpec mSecretKeySpec;

private IvParameterSpec mIvParameterSpec;


public StreamingCipherInputStream(InputStream inputStream, Cipher cipher, 

    SecretKeySpec secretKeySpec, IvParameterSpec ivParameterSpec) {

    super(inputStream, cipher);

    mUpstream = inputStream;

    mCipher = cipher;

    mSecretKeySpec = secretKeySpec;

    mIvParameterSpec = ivParameterSpec; }

@Override

public int read(byte[] b, int off, int len) throws IOException {

    return super.read(b, off, len);  }

public long forceSkip(long bytesToSkip) throws IOException {

    long skipped = mUpstream.skip(bytesToSkip);

    try {

        int skip = (int) (bytesToSkip % AES_BLOCK_SIZE);

        long blockOffset = bytesToSkip - skip;

        long numberOfBlocks = blockOffset / AES_BLOCK_SIZE;


        BigInteger ivForOffsetAsBigInteger = new BigInteger(1, 

        mIvParameterSpec.getIV()).add(BigInteger.valueOf(numberOfBlocks));

        byte[] ivForOffsetByteArray = ivForOffsetAsBigInteger.toByteArray();

        IvParameterSpec computedIvParameterSpecForOffset;

        if (ivForOffsetByteArray.length < AES_BLOCK_SIZE) {

            byte[] resizedIvForOffsetByteArray = new byte[AES_BLOCK_SIZE];

            System.arraycopy(ivForOffsetByteArray, 0, resizedIvForOffsetByteArray, 

            AES_BLOCK_SIZE - ivForOffsetByteArray.length, ivForOffsetByteArray.length);

            computedIvParameterSpecForOffset = new IvParameterSpec(resizedIvForOffsetByteArray);

        } else {

            computedIvParameterSpecForOffset = new IvParameterSpec(ivForOffsetByteArray, ivForOffsetByteArray.length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);

        }

        mCipher.init(Cipher.ENCRYPT_MODE, mSecretKeySpec, computedIvParameterSpecForOffset);

        byte[] skipBuffer = new byte[skip];

        mCipher.update(skipBuffer, 0, skip, skipBuffer);

        Arrays.fill(skipBuffer, (byte) 0);

    } catch (Exception e) {

        return 0;

    }

    return skipped;

}

@Override

public int available() throws IOException {

    return mUpstream.available();}


查看完整回答
反對 回復 2023-06-14
  • 2 回答
  • 0 關(guān)注
  • 278 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號