JAVA Cipher 加密C 語言無法解密問題總結
問題
AES演算法(DES等其他演算法一樣)。AES演算法有四種模式 CBC/ECB/CFB/OFB,這四種Java和C都有實現。AES演算法還有末尾的填充(padding),java支援的padding方式有三種NoPadding/PKCS5Padding/,而C卻不能顯式的設定padding方式,預設的padding就是在末尾加 '\0'。這是一個大坑,多少人都坑在這了。另外,網上很多JAVA AES演算法,很多都用SecureRandom,如果你的程式碼中出現了SecureRandom這個東西,那麼你再也不能用C解出來了。

password.jpeg
ofollow,noindex">https://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#trans
Creating a Cipher Object
Cipher objects are obtained by using one of the Cipher getInstance() static factory methods. Here, the algorithm name is slightly different than with other engine classes, in that it specifies not just an algorithm name, but a "transformation". A transformation is a string that describes the operation (or set of operations) to be performed on the given input to produce some output. A transformation always includes the name of a cryptographic algorithm (e.g., AES), and may be followed by a mode and padding scheme.
Cipher
物件是通過使用 Cipher getInstance()
靜態工廠方法獲得的。這裡,演算法名稱與其他引擎類略有不同,因為它不僅指定演算法名稱,而且指定“轉換”。轉換是描述要對給定輸入執行的操作(或一組操作)以產生某些輸出的字串。轉換總是包含加密演算法(例如AES)的名稱,然後可能是模式和填充方案。
A transformation is of the form:
"algorithm/mode/padding" or
"algorithm"
For example, the following are valid transformations:
"AES/CBC/PKCS5Padding" "AES"
If just a transformation name is specified, the system will determine if there is an implementation of the requested transformation available in the environment, and if there is more than one, returns there is a preferred one.
If both a transformation name and a package provider are specified, the system will determine if there is an implementation of the requested transformation in the package requested, and throw an exception if there is not.
It is recommended to use a transformation that fully specifies the algorithm, mode, and padding. By not doing so, the provider will use a default. For example, the SunJCE and SunPKCS11 providers uses ECB
(預設模式) as the default mode, and PKCS5Padding
(預設對齊方式) as the default padding for many symmetric ciphers.
This means that in the case of the SunJCE provider:
Cipher c1 = Cipher.getInstance("AES/ECB/PKCS5Padding");
and
Cipher c1 = Cipher.getInstance("AES");
are equivalent statements.
因為預設模式和預設的對齊方式,上邊的兩條語句是等價的.
https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
Cipher
Cipher The algorithms are specified as transformations. Implementations must support the key sizes in parentheses. AES/CBC/NoPadding (128)
- AES/CBC/PKCS5Padding (128)
- AES/ECB/NoPadding (128)
- AES/ECB/PKCS5Padding (128)
- DES/CBC/NoPadding (56)
- DES/CBC/PKCS5Padding (56)
- DES/ECB/NoPadding (56)
- DES/ECB/PKCS5Padding (56)
- DESede/CBC/NoPadding (168)
- DESede/CBC/PKCS5Padding (168)
- DESede/ECB/NoPadding (168)
- DESede/ECB/PKCS5Padding (168)
- RSA/ECB/PKCS1Padding (1024, 2048)
- RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
- RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
總結:
異構語言加解密在保證金鑰一致的前題下,還要保證以上三個引數是一致的,對於密碼和加密原文要注意添充模式,如果不沒有實現,需要手動添充。
demo見下文