Path: blob/master/test/jdk/java/security/MessageDigest/TestSameValue.java
41149 views
/*1* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import static java.lang.System.out;24import java.nio.ByteBuffer;25import java.security.DigestException;26import java.security.MessageDigest;27import java.security.NoSuchAlgorithmException;28import java.security.Security;29import jdk.test.lib.RandomFactory;3031/**32* @test33* @bug 8050371 815605934* @summary Check md.digest(data) value whether same with digest output value35* with various update/digest methods.36* @author Kevin Liu37* @key randomness38* @library /test/lib39* @build jdk.test.lib.RandomFactory40* @run main TestSameValue41*/4243public class TestSameValue {4445public static void main(String[] args) throws Exception {46TestSameValue test1 = new TestSameValue();47test1.run();48}4950private void run() throws Exception {5152byte[] data = new byte[6706];53MessageDigest md = null;54// Initialize input data55RandomFactory.getRandom().nextBytes(data);5657String[] algorithmArr = { "SHA", "Sha", "MD5", "md5", "SHA-224",58"SHA-256", "SHA-384", "SHA-512", "SHA3-224", "SHA3-256",59"SHA3-384", "SHA3-512" };6061for (String algorithm : algorithmArr) {62md = MessageDigest.getInstance(algorithm);6364for (UpdateDigestMethod updateMethod : UpdateDigestMethod65.values()) {66byte[] output = updateMethod.updateDigest(data, md);67// Get the output and the "correct" one68byte[] standard = md.digest(data);69// Compare input and output70if (!MessageDigest.isEqual(output, standard)) {71throw new RuntimeException(72"Test failed at algorithm/provider/numUpdate:"73+ algorithm + "/" + md.getProvider()74+ "/" + updateMethod);75}76}77}7879out.println("All "80+ algorithmArr.length * UpdateDigestMethod.values().length81+ " tests Passed");82}8384private static enum UpdateDigestMethod {8586/*87* update the data one by one using method update(byte input) then do88* digest (giving the output buffer, offset, and the number of bytes to89* put in the output buffer)90*/91UPDATE_DIGEST_BUFFER {92@Override93public byte[] updateDigest(byte[] data, MessageDigest md)94throws DigestException {95for (byte element : data) {96md.update(element);97}98byte[] output = new byte[md.getDigestLength()];99int len = md.digest(output, 0, output.length);100if (len != output.length) {101throw new RuntimeException(102"ERROR" + ": digest length differs!");103}104return output;105}106},107108/*109* update the data one by one using method update(byte input) then do110* digest111*/112UPDATE_DIGEST {113@Override114public byte[] updateDigest(byte[] data, MessageDigest md) {115for (byte element : data) {116md.update(element);117}118return md.digest();119}120},121122/*123* update all the data at once as a block, then do digest ( giving the124* output buffer, offset, and the number of bytes to put in the output125* buffer)126*/127UPDATE_BLOCK_DIGEST_BUFFER {128@Override129public byte[] updateDigest(byte[] data, MessageDigest md)130throws DigestException {131md.update(data);132byte[] output = new byte[md.getDigestLength()];133int len = md.digest(output, 0, output.length);134if (len != output.length) {135throw new RuntimeException(136"ERROR" + ": digest length differs!");137}138return output;139}140},141142// update all the data at once as a block, then do digest143UPDATE_BLOCK_DIGEST {144@Override145public byte[] updateDigest(byte[] data, MessageDigest md) {146md.update(data);147return md.digest();148}149},150151/*152* update the leading bytes (length is "data.length-LASTNBYTES") at once153* as a block, then do digest (do a final update using the left154* LASTNBYTES bytes which is passed as a parameter for the digest155* method, then complete the digest)156*/157UPDATE_LEADING_BLOCK_DIGEST_REMAIN {158@Override159public byte[] updateDigest(byte[] data, MessageDigest md) {160byte[] mainPart = new byte[data.length - LASTNBYTES];161for (int i = 0; i < mainPart.length; i++) {162mainPart[i] = data[i];163}164for (int j = 0; j < LASTNBYTES; j++) {165REMAIN[j] = data[data.length - LASTNBYTES + j];166}167md.update(mainPart);168return md.digest(REMAIN);169}170},171172/*173* update the data 2 bytes each time, after finishing updating, do174* digest (giving the output buffer, offset, and the number of bytes to175* put in the output buffer)176*/177UPDATE_BYTES_DIGEST_BUFFER {178@Override179public byte[] updateDigest(byte[] data, MessageDigest md)180throws DigestException {181182for (int i = 0; i < data.length / 2; i++) {183md.update(data, i * 2, 2);184}185byte[] output = new byte[md.getDigestLength()];186int len = md.digest(output, 0, output.length);187if (len != output.length) {188throw new RuntimeException(189"ERROR" + ": digest length differs!");190}191return output;192}193},194195/*196* update the data 2 bytes each time, after finishing updating, do197* digest198*/199UPDATE_BYTES_DIGEST {200@Override201public byte[] updateDigest(byte[] data, MessageDigest md) {202for (int i = 0; i < data.length / 2; i++) {203md.update(data, i * 2, 2);204}205return md.digest();206}207},208209/*210* update the data one by one using method update(byte[] input, int211* offset, int len) for the leading bytes (length is212* "data.length-LASTNBYTES"), then do digest (do a final update using213* the left LASTNBYTES bytes which is passed as a parameter for digest214* method then complete the digest)215*/216UPDATE_BUFFER_LEADING_DIGEST_REMAIN {217@Override218public byte[] updateDigest(byte[] data, MessageDigest md) {219for (int i = 0; i < data.length - LASTNBYTES; i++) {220md.update(data, i, 1);221}222for (int j = 0; j < LASTNBYTES; j++) {223REMAIN[j] = data[data.length - LASTNBYTES + j];224}225return md.digest(REMAIN);226}227},228229/*230* update the data one by one using method update(byte input) for the231* leading bytes (length is "data.length-LASTNBYTES"), then do digest232* (do a final update using the left LASTNBYTES bytes which is passed as233* a parameter for digest method, then complete the digest)234*/235UPDATE_LEADING_DIGEST_REMAIN {236@Override237public byte[] updateDigest(byte[] data, MessageDigest md) {238for (int i = 0; i < data.length - LASTNBYTES; i++) {239md.update(data[i]);240}241for (int j = 0; j < LASTNBYTES; j++) {242REMAIN[j] = data[data.length - LASTNBYTES + j];243}244return md.digest(REMAIN);245}246},247248/*249* update all the data at once as a ByteBuffer, then do digest (giving250* the output buffer, offset, and the number of bytes to put in the251* output buffer)252*/253UPDATE_BYTE_BUFFER_DIGEST_BUFFER {254@Override255public byte[] updateDigest(byte[] data, MessageDigest md)256throws DigestException {257md.update(ByteBuffer.wrap(data));258byte[] output = new byte[md.getDigestLength()];259int len = md.digest(output, 0, output.length);260if (len != output.length) {261throw new RuntimeException(262"ERROR" + ": digest length differs!");263}264return output;265}266},267268// update all the data at once as a ByteBuffer, then do digest269UPDATE_BYTE_BUFFER_DIGEST {270@Override271public byte[] updateDigest(byte[] data, MessageDigest md) {272md.update(ByteBuffer.wrap(data));273return md.digest();274}275},276277/*278* update the leading bytes (length is "data.length-LASTNBYTES") at once279* as a ByteBuffer, then do digest (do a final update using the left280* LASTNBYTES bytes which is passed as a parameter for the digest281* method, then complete the digest)282*/283UPDATE_BYTE_BUFFER_LEADING_DIGEST_REMAIN {284@Override285public byte[] updateDigest(byte[] data, MessageDigest md) {286byte[] mainPart = new byte[data.length - LASTNBYTES];287for (int i = 0; i < mainPart.length; i++) {288mainPart[i] = data[i];289}290for (int j = 0; j < LASTNBYTES; j++) {291REMAIN[j] = data[data.length - LASTNBYTES + j];292}293md.update(ByteBuffer.wrap(mainPart));294return md.digest(REMAIN);295}296};297298private static final int LASTNBYTES = 5;299private static final byte[] REMAIN = new byte[LASTNBYTES];300301public abstract byte[] updateDigest(byte[] data, MessageDigest md)302throws DigestException;303}304}305306307