CAVP プログラムからのテスト ベクトルを使用して、Sun JCE を使用して署名検証をコーディングしようとしています。
公開鍵の指数、係数、およびメッセージと署名が与えられます。私は次のことを行います:
private static boolean verifySignature(String algo, PrintStream oPS, byte[] message, byte[] modulus, byte[] exponent, byte[] sigBytes, int saltlen) throws Exception
{
Signature sig = Signature.getInstance(algo);
KeyFactory keyMaker = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
new BigInteger(modulus),
new BigInteger(exponent));
RSAPublicKey pubKey = (RSAPublicKey)keyMaker.generatePublic(pubKeySpec);
System.out.println("algorithm is " + algo);
sig.initVerify(pubKey);
Utils.outputValue("n", modulus, modulus.length, System.out, false);
Utils.outputValue("e", exponent, exponent.length, System.out, false);
Utils.outputValue("Msg", message, message.length, System.out, false);
Utils.outputValue("S", sigBytes, sigBytes.length, System.out, false);
BigInteger Nvalue = pubKey.getPublicExponent();
Utils.outputValue("key value of n", Nvalue.toByteArray(), System.out, false);
BigInteger Evalue=pubKey.getModulus();
Utils.outputValue("key value of e", Evalue.toByteArray(), System.out, false);
sig.update(message);
if(sig.verify(sigBytes))
oPS.println("Result = P");
else
oPS.println("Result = F");
. . .
アルゴは「SHA1withRSA」のようなもので、示されているように公開鍵を作成します。キー自体から得られたモジュラスと指数をリストすると、それらは逆になっています。
n = 009de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 Msg = 64b13df4b008ccccd5ce146018481c2568bbe2b93ec658d1c7f4ad734592cd65b3be2be5a7c1be9a7d9f49cbb2ece0cf8ee0a8c406aede84e0121bd51829d6e083862ae5b282d92c19d3923f70616f565a55c2134572116f91a85ff5f4e6ad2e1d31c15c97f3266af19574241c4fd2a4143fb80cc2b9fa7b22df0239a1715c35 S =5b4458f6aeff91c4699ee9bdf8757987fb8db229814a2992945ac53bcf19b9179e53cfed258726d205107ac000d41e570fe8c4fb321fc9b4b5469c60cd20032195f314ba6e6b0b30a51c9834242daa1ce525ec90380106568e782ea164baeda5d884defe6e720e9dd63618b823412445e17f991a6daa21bd62bdc73d7d8a20e5 key value of n = 03 key value of e = 009de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f009de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f009de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f
これらのテストの一部は失敗するはずですが、一部は成功するはずです。どれも正しく検証されていません...何か考えはありますか?ありがとう。
アプリケーションは以下のとおりで、その後に 1 セットのサンプル入力が続きます。
package cavp.rsa;
import cavp.*;
import java.io.*;
import java.security.KeyFactory;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.security.PublicKey;
import java.util.Date;
import java.math.BigInteger;
public class RSASigVerify
{
private static boolean verboseFlag=false;
public static void main(String[] args) throws Exception
{
String requestFile;
String responseFile;
int saltLen=-1;
int argstart=0;
if(args.length < 2)
throw new Exception("missing parameters");
if(args.length == 3) {
if(args[0].equals("-saltlen")) {
saltLen=Integer.parseInt(args[1]);
if(saltLen < 0)
throw new Exception("bad -saltlen parameter ");
argstart=2;
} else {
if(args[0].equals("-x931")) {
saltLen=-2;
argstart=1;
}
} else {
if(args.length > 3)
throw new Exception("invalid invocation");
}
requestFile=args[argstart];
responseFile=args[argstart+1];
if(processFile(requestFile, responseFile, saltLen))
System.out.println("Failed to process file " + requestFile);
else
System.out.println("Processing complete for " + requestFile);
}
private static boolean processFile(String rqfn, String rspfn, int saltLen) throws Exception
{
File inFile = new File(rqfn), outFile = new File(rspfn);
if(!inFile.exists() || !inFile.isFile() || !inFile.canRead()) {
System.out.println("Bad input File " + rqfn);
return true;
}
FileReader inFR = new FileReader(inFile);
BufferedReader inBR = new BufferedReader(inFR);
PrintStream outPS = new PrintStream(outFile);
String input, keyword, value, digestType=null;
int p, v, q, i, lnum=0;
byte[] Msg=null, nBytes=null, eBytes=null, sigBytes=null;
boolean msgFound=false, nFound=false, eFound=false, sigFound=false;
try {
while((input = inBR.readLine()) != null ) {
lnum++;
if((p = input.indexOf('=')) < 0) {
outPS.println(input);
continue;
}
if(input.charAt(p-1) == ' ')
keyword=input.substring(0,p-1);
else
keyword=input.substring(0, p);
p++;
for(i=p; i<input.length(); i++) {
if(input.charAt(i) == ' ')
p++;
else
break;
}
if((v = input.indexOf('\n')) > 0) {
for(q=v-1; q>p+1; q--) {
if(input.charAt(q) != ' ')
break;
}
} else {
if((v = input.indexOf(' ', p)) > 0) {
q=v-1;
} else {
q=input.length();
}
}
value=input.substring(p,q);
if(keyword.indexOf("n") >= 0) {
nBytes=Utils.hexStringToByteArray(value);
if(nBytes.length <= 0) {
System.out.println("bad value for modulus");
return true;
}
nFound=true;
} else {
if(keyword.equals("e")) {
eBytes=Utils.hexStringToByteArray(value);
if(eBytes.length <= 0) {
System.out.println("bad value for private exponent");
return true;
}
eFound=true;
} else {
if(keyword.equals("SHAAlg")) {
if(!value.equals("SHA1") && !value.equals("SHA224") && !value.equals("SHA256") && !value.equals("SHA384") &&
!value.equals("SHA512")) {
System.out.println("Bad SHAAlg parameter " + input);
return true;
}
digestType=value + "withRSA";
} else {
if(keyword.equals("Msg")) {
if(msgFound) {
System.out.println("more than one Msg found");
return true;
} else
msgFound=true;
String tempMsg;
if((value.length() & 0x01) != 0) {
tempMsg="0" + value;
} else {
tempMsg=value;
}
Msg=Utils.hexStringToByteArray(tempMsg);
if(Msg.length <= 0) {
System.out.println("bad Msg parameter");
return true;
}
} else {
if(keyword.equals("S")) {
sigBytes=Utils.hexStringToByteArray(value);
if(sigBytes.length <= 0) {
System.out.println("bad signature parameter");
return true;
}
sigFound=true;
} else {
if(keyword.equals("Result")) {
continue;
}
}
}
}
}
}
outPS.println(input);
if(digestType != null && msgFound && nFound && eFound && sigFound) {
if(verifySignature(digestType, outPS, Msg, nBytes, eBytes, sigBytes, saltLen)) {
throw new Exception("error in digest generator");
}
msgFound=false;
eFound=false;
sigFound=false;
}
}
} catch( FileNotFoundException e) {
System.out.println("error processing file");
}
inFR.close();
outPS.close();
return false;
}
private static boolean verifySignature(String algo, PrintStream oPS, byte[] message, byte[] modulus, byte[] exponent, byte[] sigBytes, int saltlen) throws Exception
{
// yet to implement saltLen == -2 for X9.31 padding
// saltLen >= 0 for PSS Signatures
Signature sig = Signature.getInstance(algo);
KeyFactory keyMaker = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
new BigInteger(modulus),
new BigInteger(exponent));
RSAPublicKey pubKey = (RSAPublicKey)keyMaker.generatePublic(pubKeySpec);
System.out.println("algorithm is " + algo);
sig.initVerify(pubKey);
sig.update(message);
if(sig.verify(sigBytes))
oPS.println("Result = P");
else
oPS.println("Result = F");
return false;
}
}
以下は、入力からの 1 つのベクトルです。
# CAVS 11.5
# "SigVer PKCS#1 Ver 1.5" information for
# Mod sizes selected: 1024 2048
# SHA Algorithm selected:SHA1 SHA256
# Generated on Mon Nov 28 14:03:58 2011
[mod = 1024]
n = 9de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d>51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141>828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f
SHAAlg = SHA1
e = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>0000000000000000000000000000000000000000000000000000000000000000000000000003
Msg = 64b13df4b008ccccd5ce146018481c2568bbe2b93ec658d1c7f4ad734592cd65b3be2be5a7c1be9a7d9f49cbb2>ece0cf8ee0a8c406aede84e0121bd51829d6e083862ae5b282d92c19d3923f70616f565a55c2134572116f91a8>5ff5f4e6ad2e1d31c15c97f3266af19574241c4fd2a4143fb80cc2b9fa7b22df0239a1715c35
S = 5b4458f6aeff91c4699ee9bdf8757987fb8db229814a2992945ac53bcf19b9179e53cfed258726d205107ac000>d41e570fe8c4fb321fc9b4b5469c60cd20032195f314ba6e6b0b30a51c9834242daa1ce525ec90380106568e78>2ea164baeda5d884defe6e720e9dd63618b823412445e17f991a6daa21bd62bdc73d7d8a20e5*
合格するベクターファイルは次のとおりです。
# CAVS 11.5
# "SigVer PKCS#1 Ver 1.5" information for
# Mod sizes selected: 1024 2048
# SHA Algorithm selected:SHA1 SHA256
# Generated on Mon Nov 28 14:03:58 2011
[mod = 1024]
n = 9de541c71a95389d9e8619ea1d6e2c69ed6c703701e518351676022ab98395d6b35a38b024f92bce6dd1c5be9d51dffd1687d19dceee73f2c73e4436b955231255f6e3e360ba84462311e10e65932fe069bed2d42c5bf2f88141828bdad3796184870cb8cf3019da264e56b39eccf7224d43a1b98d788b40a4042aac790e946f
SHAAlg = SHA1
e = 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
Msg = fe196459e8232a9f94e8c93d88ddae7d38be7a10e2dd03ffb7bb9be43bd59659eec006b12c78c9e652f6c6d3220073a369459b8adea95eb34ede7979f634c7d931b208275365e201d4f82582b18553b70fab605721e1b6ae4d097cdb8a49183b0d16f22524917bd862176fb1fc1357a2731751df732c13dafc662e72bfbb9067
S = 94af4ce7f323d1bf4904a673d2884e30a55a108c44e4eb2bfc0a0f061f46fefe23fe74c760e947bd1fbf1bb1a30d66b3d7dccfb425d3a6551dd444f90d4f06c3e0da6dc3c7a45e062b08d24553f0091acae47ffaae495e13da66308dd9e0be87e2b960ab823f83e55815b66a1076ab238cc3883cbf7312521d0988214bb07d96