我发现了一个似乎只影响部分三星(到目前为止)设备的问题。 这是须藤:
非法 block 大小异常
基本上,如果我坚持使用一个密码,同时在尝试解密另一个密码的过程中解密另一个密码,我们会收到异常。
我们试过 Nexus 6P、Nexus 5X、Note 4(没问题) 我们在(S7、S7 Edge、S6)上看到了这个问题
代码:
public void createKey(String keyName) {
KeyPairGenerator generator = null;
try {
generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
Log.e("MainActivity", e.getMessage());
e.printStackTrace();
}
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.build();
try {
generator.initialize(spec);
} catch (InvalidAlgorithmParameterException e) {
Log.e("MainActivity", e.getMessage());
}
generator.generateKeyPair();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createKey("Key");
createKey("Key1");
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("Key", null);
PrivateKey privateKey = (PrivateKey) privateKeyEntry.getPrivateKey();
Cipher c;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
} else {
c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
}
c.init(Cipher.DECRYPT_MODE, privateKey);
mCancellationSignal = new CancellationSignal();
String ecryptedS1 = doEncription("Key1");
KeyStore ks1 = KeyStore.getInstance("AndroidKeyStore");
ks1.load(null);
KeyStore.PrivateKeyEntry privateKeyEntry1 = (KeyStore.PrivateKeyEntry) ks1.getEntry("Key1", null);
PrivateKey privateKey1 = (PrivateKey) privateKeyEntry1.getPrivateKey();
Cipher c1;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
c1 = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
} else {
c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
}
c1.init(Cipher.DECRYPT_MODE, privateKey1);
String org = "";
try {
org = new String(c1.doFinal(Base64.decode(ecryptedS1, Base64.DEFAULT|Base64.NO_WRAP)));
Log.d("MainActivity", "org key1" + org);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
org = null;
try {
org = new String(c.doFinal(Base64.decode(doEncription("Key"), Base64.DEFAULT|Base64.NO_WRAP)));
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
异常(exception):
10-04 14:29:13.919 15568-15568/com.example.rollandliu.decryption W/System.err: javax.crypto.IllegalBlockSizeException
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:486)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at javax.crypto.Cipher.doFinal(Cipher.java:1502)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at com.example.rollandliu.decryption.MainActivity$3.onClick(MainActivity.java:248)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.view.View.performClick(View.java:5702)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.widget.TextView.performClick(TextView.java:10885)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.view.View$PerformClick.run(View.java:22533)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.os.Looper.loop(Looper.java:158)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7229)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at java.lang.reflect.Method.invoke(Native Method)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
10-04 14:29:13.929 15568-15568/com.example.rollandliu.decryption W/System.err: Caused by: android.security.KeyStoreException: Invalid operation handle
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err: at android.security.KeyStore.getKeyStoreException(KeyStore.java:940)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err: at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:132)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err: at android.security.keystore.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:217)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err: at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:473)
10-04 14:29:13.939 15568-15568/com.example.rollandliu.decryption W/System.err: ... 12 more
最佳答案
它有点过时了,但我会在这里发布一个答案,以防一些好人试图解决这个问题。
三星设备在其 JVM 中运行的 Cipher 类有不同的实现,在我的例子中,我只需要对其进行操作同步。
它为我解决了问题,所以我可以猜测三星的 Cipher 不是线程安全的。
干杯!
关于android - 为什么我不能在三星 S6 和 S7 上执行多个 keystore 密码解密?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39859579/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2